我想知道是否有可能在註冊名稱的某個條件下解決Unity中的所有依賴項。Unity - 通過名稱條件解析所有條件
例如: 重新註冊註冊名稱的所有接口以「ProcessA」開頭。
如果沒有辦法做到這一點,那麼或許我該如何擴展Unity來允許這樣做。
我想知道是否有可能在註冊名稱的某個條件下解決Unity中的所有依賴項。Unity - 通過名稱條件解析所有條件
例如: 重新註冊註冊名稱的所有接口以「ProcessA」開頭。
如果沒有辦法做到這一點,那麼或許我該如何擴展Unity來允許這樣做。
你應該能夠使用Registrations
做到這一點,我會建議一個擴展方法,而不是直接擴展統一:
var matches = c.Resolve<IMyService>(name => name.StartsWith("ProcessA"));
使用這種擴展方法:
public static class MyUnityExtensions
{
public static IEnumerable<T> Resolve<T>(this IUnityContainer c, Func<string, bool> match)
{
var matches = c.Registrations.Where(r => match(r.Name));
foreach (var registration in matches)
{
yield return c.Resolve<T>(registration.Name);
}
}
}
只是增加了邁克爾的答案,我擴展了這一點,以允許您使用相同的名稱進行註冊,但使用全部解決方法僅解決針對該名稱註冊的那些名稱。
public struct ScopedName<T>
{
private const string Separator = "|";
private readonly string _name;
private readonly string _registrationName;
public ScopedName(string name)
: this()
{
_name = name;
_registrationName = name + Separator + typeof(T).FullName;
}
public static implicit operator string(ScopedName<T> scopedName)
{
return scopedName._registrationName;
}
public bool IsMatach(string other)
{
if (string.IsNullOrWhiteSpace(other))
{
return false;
}
var i = other.IndexOf(Separator, StringComparison.InvariantCulture);
if (i < 0)
{
return false;
}
return string.Equals(_name, other.Substring(0, i), StringComparison.InvariantCulture);
}
}
public static class UnityEx
{
public static IUnityContainer RegisterType<TFrom, TTo>(
this IUnityContainer container,
ScopedName<TTo> scopedName,
LifetimeManager lifetimeManager,
params InjectionMember[] injectionMembers) where TTo : TFrom
{
return container.RegisterType(typeof(TFrom), typeof(TTo), scopedName, lifetimeManager, injectionMembers);
}
public static IEnumerable<T> ResolveAll<T>(this IUnityContainer container, ScopedName<T> name, params ResolverOverride[] resolverOverrides)
{
var matches = container.Registrations.Where(r => name.IsMatach(r.Name));
foreach (var registration in matches)
{
yield return container.Resolve<T>(registration.Name, resolverOverrides);
}
}
}
允許用於註冊和解析這樣的:
container.RegisterType<IFoo, Foo1>(new ScopedName<Foo1>("Scope1"), new HierarchicalLifetimeManager());
container.RegisterType<IFoo, Foo2>(new ScopedName<Foo2>("Scope1"), new HierarchicalLifetimeManager());
container.RegisterType<IFoo, Foo3>(new ScopedName<Foo3>("Scope2"), new HierarchicalLifetimeManager());
container.RegisterType<IFoo, Foo4>(new ScopedName<Foo4>("Scope2"), new HierarchicalLifetimeManager());
var scope1Foos = container.ResolveAll(new ScopedName<IFoo>("Scope1"));
var scope2Foos = container.ResolveAll(new ScopedName<IFoo>("Scope2"));
scope1Foos將容器Foo1和foo2的兩者scope2Foos將包含Foo3和Foo4
調用到容器直接通常被認爲是一種抗-模式。如果您能夠爲您的問題提供更多背景信息(您想解決什麼問題),或許我們可以爲您提供一些關於如何改進設計的提示。 – Steven 2011-05-08 19:11:23