引用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();//获取实例对象
//构造函数
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));
}
}
}
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