Microsoft Unity--IOC/DI

引用Microsoft.Practices.Unity.dll;Microsoft.Practices.Configuration.dll;

Unity的依赖注入流程:Register, Resolve, Dispose

Unity的依赖注入类型:实例注入(Instance Registration),简单类型注入(Simple Type Registration),构造器注入(Constructor Registration),属性注入(Property Registration),方法注入(Method Registration)

一、Register:

用来建立抽象类型与具体类型之间的映射:

var container = new UnityContainer();
container.RegisterType();//表示让container实例化一个TenantStore对象给需要一个ITenantStore对象的类
1.Instance Registraton:

StorageAccount account = 
  ApplicationConfiguration.GetStorageAccount("DataConnectionString");
container.RegisterInstance(account);
RegisterInstance是注册实例 (instance),默认情况下每次使用 Resolve 方法都获得同一个对象,即单例模式,在该container中只存在一个该对象;

使用RegisterType和ContainerControlledLifetimeManager  也可以创建单例:

container.RegisterType(new ContainerControlledLifetimeManager());

2.Simple Type Registration:

container.RegisterType();//创建映射

var surveyStore = container.Resolve();//获取实例对象

3.Constructor Registration:

//构造函数
public DataTable(StorageAccount account,
  IRetryPolicyFactory retryPolicyFactory, string tableName)
{
  ...
}
var storageAccountType = typeof(StorageAccount);
var retryPolicyFactoryType = typeof(IRetryPolicyFactory);

container
  .RegisterType, DataTable>(
    new InjectionConstructor(storageAccountType,//对于构造函数参数中的类型对象,使用InjectionConstructor来注入
      retryPolicyFactoryType, Constants.SurveysTableName))
  .RegisterType, DataTable>(
    new InjectionConstructor(storageAccountType,
      retryPolicyFactoryType, Constants.QuestionsTableName));

4.泛型类型注入(Registering open Generics):使用RegisterType另一个重载版本:

//MessageQueue.cs:   
 public MessageQueue(StorageAccount account, IRetryPolicyFactory retryPolicyFactory)
      : this(account, retryPolicyFactory, typeof(T).Name.ToLowerInvariant())
    {
    }
container.RegisterType(
  typeof(IMessageQueue<>),
  typeof(MessageQueue<>),
  new InjectionConstructor(storageAccountType,
    retryPolicyFactoryType, typeof(string)));
container.Resolve>(...);//获取实例对象

二、Resolve:

用来获得通过依赖注入实例化后的实例对象。

1.simple resolve:

首先创建一个unity container, 然后注册所有的Registrations,最后调用Resolve来获得实例对象并调用Initialize方法来初始化

static void Main(string[] args)
{
  using (var container = new UnityContainer())
  {
    ContainerBootstrapper.RegisterTypes(container);

    container.Resolve().Initialize();
    container.Resolve().Initialize();
    container.Resolve().Initialize();
 
    Console.WriteLine("Done");
    Console.ReadLine();
  }
}
在Initialize方法执行完后, container就被disposed了。

2. Resolving in MVC application:

在mvc中container必须能够注入MVC controller实例。

引入Microsoft.Practices.Unity.dll;Microsoft.Practices.Unity.MVC.dll;Microsoft.Practice.Configuration.dll;

在APP_START文件夹中建立UnityConfig.cs:

public static void RegisterTypes(IUnityContainer container)
{
    // NOTE: To load from web.config uncomment the line below...
    // container.LoadConfiguration();

    // TODO: Register your types here
    // ContainerBootstrapper.RegisterTypes(container);
}
APS.NET MVC Unity 提供了一个UnityDependencyResolver类来从container中获取controllers对象。

var controller = container.Resolve();
三、Dispose:

释放不再被引用的通过依赖注入的实例对象,以便GC回收。


五、Demo:

引用:Microsoft.Practices.Unity.dll;Microsoft.Practices.Unity.MVC.dll;Microsoft.Practice.Configuration.dll;

1.ContainerBootstrapper.cs:

将所有的抽象类型与具体类型的映射注册在ContainerBootstrapper.cs:中:(或在配置文件中进行注册)

public class ContainerBootstrapper
  {
    public static void RegisterTypes(IUnityContainer container)
    {
      Trace.WriteLine(string.Format("Called RegisterTypes in ContainerBootstrapper"), "UNITY");

      var storageAccountType = typeof(StorageAccount);
      var retryPolicyFactoryType = typeof(IRetryPolicyFactory);

      // Instance registration
      StorageAccount account = 
        ApplicationConfiguration.GetStorageAccount("DataConnectionString");
      container.RegisterInstance(account);

      // Register factories
      container
        .RegisterInstance(
          new ConfiguredRetryPolicyFactory())
        .RegisterType(
            new ContainerControlledLifetimeManager());

      // Register table types
      container
        .RegisterType, DataTable>(
          new InjectionConstructor(storageAccountType,
            retryPolicyFactoryType, Constants.SurveysTableName))
        .RegisterType, DataTable>(
          new InjectionConstructor(storageAccountType,
            retryPolicyFactoryType, Constants.QuestionsTableName));

      // Register message queue type, use typeof with open generics
      container
        .RegisterType(
            typeof(IMessageQueue<>),
            typeof(MessageQueue<>),
            new InjectionConstructor(storageAccountType,
              retryPolicyFactoryType, typeof(String)));

      // Register blob types
      container
        .RegisterType>,
          EntitiesBlobContainer>>(
            new InjectionConstructor(storageAccountType,
              retryPolicyFactoryType, Constants.SurveyAnswersListsBlobName))
        .RegisterType,
          EntitiesBlobContainer>(
            new InjectionConstructor(storageAccountType,
              retryPolicyFactoryType, Constants.TenantsBlobName))
        .RegisterType,
          FilesBlobContainer>(
            new InjectionConstructor(storageAccountType,
              retryPolicyFactoryType, Constants.LogosBlobName, "image/jpeg"))
        .RegisterType,
          EntitiesBlobContainer>(
            new InjectionConstructor(storageAccountType,
              retryPolicyFactoryType, typeof(String)));

      // Register store types
      container
        .RegisterType()
        .RegisterType()
        .RegisterType(
          new InjectionFactory((c, t, s) => new SurveyAnswerStore(
            container.Resolve(),
            container.Resolve(),
            container.Resolve>(
              new ParameterOverride(
                "queueName", Constants.StandardAnswerQueueName)),
            container.Resolve>(
              new ParameterOverride(
                "queueName", Constants.PremiumAnswerQueueName)),
            container.Resolve>>())));
    }
  }
2.在App_Start文件夹中建立UnityConfig.cs:

namespace SurveysWebApp.App_Start
{
    /// 
    /// Specifies the Unity configuration for the main container.
    /// 
    public class UnityConfig
    {
        #region Unity Container
        private static Lazy container = new Lazy(() =>
        {
            var container = new UnityContainer();
            RegisterTypes(container);
            return container;
        });

        /// 
        /// Gets the configured Unity container.
        /// 
        public static IUnityContainer GetConfiguredContainer()
        {
            return container.Value;
        }
        #endregion

        /// Registers the type mappings with the Unity container.
        /// The unity container to configure.
        /// There is no need to register concrete types such as controllers or API controllers (unless you want to 
        /// change the defaults), as Unity allows resolving a concrete type even if it was not previously registered.
        public static void RegisterTypes(IUnityContainer container)
        {
            // NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
            // container.LoadConfiguration();

            // TODO: Register your types here
            // container.RegisterType();
            ContainerBootstrapper.RegisterTypes(container);
        }
    }
}
3.在App_Start文件夹中建立UnityMvcActivator.cs:

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(SurveysWebApp.App_Start.UnityWebActivator), "Start")]

namespace SurveysWebApp.App_Start
{
    /// Provides the bootstrapping for integrating Unity with ASP.NET MVC.
    public static class UnityWebActivator
    {
        /// Integrates Unity when the application starts.
        public static void Start() 
        {
            var container = UnityConfig.GetConfiguredContainer();

            FilterProviders.Providers.Remove(FilterProviders.Providers.OfType().First());
            FilterProviders.Providers.Add(new UnityFilterAttributeFilterProvider(container));

            DependencyResolver.SetResolver(new UnityDependencyResolver(container));

            // TODO: Uncomment if you want to use PerRequestLifetimeManager
            // Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule));
        }
    }
}

4.在Controller中:

 public class SurveysController : Controller
    {
        private readonly ISurveyStore surveyStore;
        private readonly ISurveyAnswerStore surveyAnswerStore;
        private readonly ITenantStore tenantStore;

        public SurveysController(
          ISurveyStore surveyStore,
          ISurveyAnswerStore surveyAnswerStore,
          ITenantStore tenantStore)
        {
          this.surveyStore = surveyStore;
          this.surveyAnswerStore = surveyAnswerStore;
          this.tenantStore = tenantStore;
        }

        public ITenantStore TenantStore
        {
          get { return this.tenantStore; }
        }

        public Tenant Tenant { get; set; }

        [HttpGet]
        public ActionResult Index(string tenant)
        {
          this.Tenant = this.tenantStore.GetTenant(tenant);

          IEnumerable surveysForTenant = this.surveyStore.GetSurveysByTenant(tenant);

          var model = this.CreateTenantPageViewData(surveysForTenant);
          model.Title = "My Surveys";

          return this.View(model);
        }
   }

配置文件方式:http://www.cnblogs.com/springyangwc/archive/2012/05/17/2506595.html

http://www.cnblogs.com/xuf22/articles/2878463.html


你可能感兴趣的:(Microsoft,Unity)