Я пытаюсь обновить Unity с версии 3.0.1304.1 до последней версии 5.11.1. Неудивительно, что есть некоторые проблемы (3.0.1304.1 довольно старый). Приведенный ниже код выполняет две вещи:
- Использование ContainerControlledLifetimeManager для всех классов, производных от некоторого базового класса X, без указания того, что для каждого класса, производного от X.
- Использование конструктора по умолчанию, когдаразрешение для всех классов, производных от базового класса Y, без указания того, что для каждого класса, производного от Y.
Документация Unity в настоящее время недостаточна и не имеет примеров. Я прочитал заметки об обновлении и обычную документацию, но я не могу заставить это работать с новой версией.
Пока у меня есть:
- Заменено
IConstructorSelectorPolicy
с ISelect<ConstructorInfo>
- Заменено
IBuilderContext
на BuilderContext
(или ref BuilderContext в функции PreBuildUp)
Но что делать с LifetimeManagerFactory
? Должен ли я получить IOCConstructorSelectorPolicy
из ISelect<ConstructorInfo>
и затем заменить IOCConstructorSelectorPolicy.SelectConstructor
на Select
(согласно интерфейсу ISelect) и как реализовать эту функцию выбора?
Я знаю, что это очень долгоснимок, и я также опубликую это на Unity 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;
}
}