我正在尝试将Unity从版本3.0.1304.1升级到最新的5.11.1。毫不奇怪,这里有一些问题(3.0.1304.1已经很老了)。下面的代码完成了两件事:
如今,统一文档稀缺且缺乏示例。我已经阅读了upgrade notes和常规文档,但无法在新版本中使用。
到目前为止,我有:
IConstructorSelectorPolicy
替换为ISelect<ConstructorInfo>
IBuilderContext
替换为BuilderContext
(或PreBuildUp函数中的ref BuilderContext)但是如何处理LifetimeManagerFactory
?我应该从IOCConstructorSelectorPolicy
派生ISelect<ConstructorInfo>
,然后IOCConstructorSelectorPolicy.SelectConstructor
替换为Select
(根据ISelect接口),以及如何实现此Select函数?
我知道这是一个很长的镜头,我也将其发布在统一的github上(作为对各种文档的要求),但希望有人可以给我一些指导。
/// <summary>
/// This class merely exists for readability: avoid having to write the class it derives from.
/// </summary>
public class IOCConfigLifetimeExtension : DefaultLifetimeManagerExtension<ContainerControlledLifetimeManager, X>
{}
/// <summary>
/// An IOC strategy to use a specific LifetimeManager (<typeparamref name="TLifetimeManager"/>) for subclasses of <typeparamref name="TBaseClass"/>.
/// </summary>
public class DefaultLifetimeManagerExtension<TLifetimeManager, TBaseClass> : UnityContainerExtension where TLifetimeManager : LifetimeManager, new()
{
protected override void Initialize()
{
var theFactory = new LifetimeManagerFactory(Context, typeof(TLifetimeManager));
Context.Strategies.Add(new DefaultLifetimeManagerStrategy(theFactory, TypePredicate), UnityBuildStage.TypeMapping);
}
private bool TypePredicate(Type type)
{
return typeof (TBaseClass).IsAssignableFrom(type);
}
}
public class DefaultLifetimeManagerStrategy : BuilderStrategy
{
public DefaultLifetimeManagerStrategy(LifetimeManagerFactory factory, Predicate<Type> typePredicate)
{
mFactory = factory;
mTypePredicate = typePredicate;
}
public override void PreBuildUp(IBuilderContext context)
{
if (context.Existing == null) {
var theLifetime = context.Policies.GetNoDefault<ILifetimePolicy>(context.BuildKey, false);
if (theLifetime == null && mTypePredicate(context.BuildKey.Type)) {
theLifetime = mFactory.CreateLifetimePolicy();
context.PersistentPolicies.Set(theLifetime, context.BuildKey);
}
}
}
private readonly LifetimeManagerFactory mFactory;
private readonly Predicate<Type> mTypePredicate;
}
/// <summary>
/// A Unity extension that prioritizes the default constructor for classes derived of Y when available, otherwise the default resolve method is used.
/// </summary>
public class IOCExtension : UnityContainerExtension
{
protected override void Initialize()
{
var theDefaultConstructorSelectorPolicy = Context.Policies.Get<IConstructorSelectorPolicy>(null);
Context.Policies.SetDefault<IConstructorSelectorPolicy>(new IOCConstructorSelectorPolicy(theDefaultConstructorSelectorPolicy));
}
public class IOCConstructorSelectorPolicy : IConstructorSelectorPolicy
{
public IOCConstructorSelectorPolicy(IConstructorSelectorPolicy defaultConstructorSelectorPolicy)
{
mDefaultConstructorSelectorPolicy = defaultConstructorSelectorPolicy;
}
public SelectedConstructor SelectConstructor(IBuilderContext context, IPolicyList resolverPolicyDestination)
{
Type theType = context.BuildKey.Type;
if (typeof(DataNode).IsAssignableFrom(theType)) {
ConstructorInfo theDefaultConstructorInfo = theType.GetConstructor(Type.EmptyTypes);
if (theDefaultConstructorInfo != null && theDefaultConstructorInfo.IsPublic) {
return new SelectedConstructor(theDefaultConstructorInfo);
}
}
return mDefaultConstructorSelectorPolicy.SelectConstructor(context, resolverPolicyDestination);
}
private readonly IConstructorSelectorPolicy mDefaultConstructorSelectorPolicy;
}
}