现在的位置: 首页 > 综合 > 正文

Unity 2.0 内置生命周期管理类 Built-In Lifetime Managers

2012年07月17日 ⁄ 综合 ⁄ 共 8814字 ⁄ 字号 评论关闭

Unity includes six lifetime managers that you can use directly in your code, but you can create your own lifetime managers to implement specific lifetime scenarios. Unity includes the following lifetime managers:

  • TransientLifetimeManager(每次重新构造新的实例)For this lifetime manager Unity creates and returns a new instance of the requested type for each call to the Resolve or ResolveAll method. This lifetime manager is used by default for all types registered using the RegisterType, method unless you specify a different lifetime manager.
  • ContainerControlledLifetimeManager(单例模式,也是RegisterInstance 方法默认的生命周期) which registers an existing object as a singleton instance. For this lifetime manager Unity returns the same instance of the registered type or object each time you call the Resolve or ResolveAll method or when the dependency mechanism injects instances into other classes. This lifetime manager effectively implements a singleton behavior for objects. Unity uses this lifetime manager by default for the RegisterInstance method if you do not specify a different lifetime manager. If you want singleton behavior for an object that Unity will create when you specify a type mapping in configuration or when you use the RegisterType method, you must explicitly specify this lifetime manager.

    If you registered a type mapping using configuration or using the RegisterType method, Unity creates a new instance of the registered type during the first call to the Resolve or ResolveAll method or when the dependency mechanism injects instances into other classes. Subsequent requests return the same instance.

    If you registered an existing instance of an object using the RegisterInstance method, the container returns the same instance for all calls to Resolve or ResolveAll or when the dependency mechanism injects instances into other classes, provided that one of the following is true:

    • You have specified a container-controlled lifetime manager
    • You have used the default lifetime manager
    • You are resolving in the same context in which you registered the instance when using a different lifetime manager.

    Once you have a reference to the proper container, call the RegisterInstance method of that container to register the existing object. Specify as the registration type an interface that the object implements, an object type from which the target object inherits, or the concrete type of the object.

    The following example creates a named (non-default) mapping by specifying the name, Email and uses the default lifetime.

    C#

    myContainer.RegisterInstance<EmailService>("Email", myEmailService);

    Visual Basic

    myContainer.RegisterInstance(Of EmailService)("Email", myEmailService)

    When the container is disposed, it calls the Dispose method of the object and allows it to be garbage collected. Therefore, you must ensure that your code does not maintain a reference to the object.

  • HierarchicalLifetimeManager(分层隔离模式,也就是每层container单独使用单例模式,在一层情况下与ContainerControlledLifetimeManager等同). For this lifetime manager, as for the ContainerControlledLifetimeManager, Unity returns the same instance of the registered type or object each time you call the Resolve or ResolveAll method or when the dependency mechanism injects instances into other classes. The distinction is that when there are child containers, each child resolves its own instance of the object and does not share one with the parent. When resolving in the parent, the behavior is like a container controlled lifetime; when resolving the parent and the child you have different instances with each acting as a container-controlled lifetime. If you have multiple children, each will resolve its own instance.

    C#

    IUnityContainer Parent = new UnityContainer();
    IUnityContainer child = Parent.CreateChildContainer();
    
    MyType newInstance = new MyType();
    Parent.RegisterInstance<MyType>(newInstance, new HierarchicalLifetimeManager()); 

    Visual Basic

    Dim Parent As IUnityContainer = New UnityContainer()
    Dim child As IUnityContainer = Parent.CreateChildContainer()
    
    Dim newInstance As New MyType()
    Parent.RegisterInstance(Of MyType)(newInstance, New HierarchicalLifetimeManager())
  • PerResolveLifetimeManager(区别于TransientLifetimeManager在递归构造中会重用已经构造的对象). For this lifetime manager the behavior is like a TransientLifetimeManager, but also provides a signal to the default build plan, marking the type so that instances are reused across the build-up object graph. In the case of recursion, the singleton behavior applies where the object has been registered with the PerResolveLifetimeManager. The following example uses the PerResolveLifetimeManager.

    C#

    public void ViewIsReusedAcrossGraph()
    {
        var container = new UnityContainer()
            .RegisterType<IPresenter, MockPresenter>()
            .RegisterType<IView, View>(new PerResolveLifetimeManager());
        var view = container.Resolve<IView>();
        var realPresenter = (MockPresenter) view.Presenter;
    }

    Visual Basic

    Public Sub ViewIsReusedAcrossGraph()
        Dim container = New UnityContainer() _
            .RegisterType(Of IPresenter, MockPresenter)() _
            .RegisterType(Of IView, View)(New PerResolveLifetimeManager())
        Dim view = container.Resolve(Of IView)()
        Dim realPresenter = DirectCast(view.Presenter, MockPresenter)
    End Sub

    The following small object graph illustrates the per-build behavior for the example. MockPresenter inherits from IPresenter and contains a View and MockPresenter object. IView contains a Presenter object and View class contains a Presenter dependency. View is reused across the graph per resolve call because View is registered with a PerResolveLifetimeManager.

    C#

    public interface IPresenter 
    { }
    
    public class MockPresenter : IPresenter
    {
        public IView View { get; set; }
    
        public MockPresenter(IView view)
        {
            View = view;
        }
    }
    
    public interface IView
    {
        IPresenter Presenter { get; set; }
    }
    
    public class View : IView
    {
        [Dependency]
        public IPresenter Presenter { get; set; }
    }

    Visual Basic

    Public Interface IPresenter
    End Interface
    
    Public Class MockPresenter
        Implements IPresenter
    
        Private _View As IView
        Public Property View() As IView
            Get
                Return _View
            End Get
            Set(ByVal value As IView)
                _View = value
            End Set
        End Property
        
        Public Sub New(ByVal view__1 As IView)
            View = view__1
        End Sub
    End Class
    
    Public Interface IView
        Property Presenter() As IPresenter
    End Interface
    
    Public Class View
        Implements IView
    
        Private _Presenter As IPresenter
        <Dependency()> _ 
        Public Property Presenter() As IPresenter
            Get
                Return _Presenter
            End Get
            Set(ByVal value As IPresenter)
                _Presenter = value
            End Set
        End Property
    
    End Class
  • PerThreadLifetimeManager(故名思议分线程). For this lifetime manager Unity returns, on a per-thread basis, the same instance of the registered type or object each time you call the Resolve or ResolveAll method or when the dependency mechanism injects instances into other classes. This lifetime manager effectively implements a singleton behavior for objects on a per-thread basis. PerThreadLifetimeManager returns different objects from the container for each thread.

    If you registered a type mapping using configuration or using the RegisterType method, Unity creates a new instance of the registered type the first time the type is resolved in a specified thread, either to answer a call to the Resolve or ResolveAll method for the registered type or to fulfill a dependency while resolving a different type. Subsequent resolutions on the same thread return the same instance.

    PerThreadLifetimeManager returns the object desired or permits the container to create a new instance if no such object is currently stored for the current thread. A new instance is also created if called on a thread other than the one that set the value.

     

    When using the PerThreadLifetimeManager, it is recommended that you use RegisterType and do not use RegisterInstance to register an object.

    When you register an instance with the PerThreadLifetimeManager, the instance is registered only for the executing thread. Calls to Resolve on other threads result in per-thread singletons for container-built instances. If you request a type registered with the PerThreadLifetimeManager in any thread other than the thread it was registered for, the lifetime container for that object finds that there is no registered instance for that thread and, therefore, permits the container to build a new instance for that thread.

    The result is that for threads other than the one registering the instance, the behavior is the same as if you registered the container lifetime with RegisterType.

    This lifetime manager does not dispose the instances it holds. The thread object is reclaimed by garbage collection when the thread is disposed, but note that the object is not disposed in the sense that the Dispose method is not invoked.

  • ExternallyControlledLifetimeManager()The ExternallyControlledLifetimeManager class provides generic support for externally managed lifetimes. This lifetime manager allows you to register type mappings and existing objects with the container so that it maintains only a weak reference to the objects it creates when you call the Resolve or ResolveAll method or when the dependency mechanism injects instances into other classes based on attributes or constructor parameters within that class. This allows other code to maintain the object in memory or dispose it and enables you to maintain control of the lifetime of existing objects or allow some other mechanism to control the lifetime. Using the ExternallyControlledLifetimeManager enables you to create your own custom lifetime managers for specific scenarios. Unity returns the same instance of the registered type or object each time you call the Resolve or ResolveAll method or when the dependency mechanism injects instances into other classes. However, since the container does not hold onto a strong reference to the object after it creates it, the garbage collector can dispose of the object if no other code is holding a strong reference to it.

 

Note:

Using the RegisterInstance method to register an existing object results in the same behavior as if you just registered the lifetime container with RegisterType. Therefore, it is recommended that you do not use the RegisterInstance method to register an existing object when using the non-default lifetime managers except for the thread in which the RegisterInstance was invoked.

抱歉!评论已关闭.