是否可以两次注册相同的接口,其中第一个解析为默认实现,第二个具有名称并解析为另一个类型。
示例:
container.RegisterType(typeof(IMyInterface), typeof(MyDefaultImplementation));
container.RegisterType(typeof(IMyInterface), typeof(MySecondImplementation),"Second Implementations name");
所以,
Resolve<IMyInterface>("non existing name")
应解决MyDefaultImplementation。
答案 0 :(得分:3)
如果你可以使用容器,你可以做一个扩展方法:
public static class UnityExtensions
{
public static T TryResolve<T>(this IUnityContainer container, string name)
{
if (container.IsRegistered<T>(name))
return container.Resolve<T>(name);
return container.Resolve<T>();
}
}
并使用它:
container.RegisterType<IMyInterface, Foo>();
container.RegisterType<IMyInterface, Bar>("bar");
var foo = container.TryResolve<IMyInterface>("non-existing");
// foo will be Foo
var bar = container.TryResolve<IMyInterface>("bar");
// bar will be Bar.
public interface IMyInterface { }
public class Foo : IMyInterface { }
public class Bar : IMyInterface { }
缺点是您需要知道何时使用扩展程序以及何时不使用...否则您可以构建自己的BuilderStrategy
。
深受影响:
Unity - loadConfiguration, how to resolve only those configured
答案 1 :(得分:2)
我对团结不够熟悉,但你开始创建自己的配置,将其添加为扩展名:
public class DefaultRegistrationFallbackConfiguration : UnityContainerExtension
{
protected override void Initialize()
{
this.Context.Registering += this.AppendRemapPolicy;
}
public override void Remove()
{
this.Context.Registering -= this.AppendRemapPolicy;
}
private void AppendRemapPolicy(object sender, RegisterEventArgs e)
{
if (e.Name != null)
return;
if (e.TypeFrom != null && e.TypeTo != null)
this.Context.Policies.SetDefault<IBuildKeyMappingPolicy>(new MapBuildKeyToDefaultPolicy(e.TypeFrom, e.TypeTo));
if (e.LifetimeManager == null)
return;
throw new NotImplementedException("TODO: lifetime management");
}
}
创建自己的IBuildKeyMappingPolicy
:
public class MapBuildKeyToDefaultPolicy : IBuildKeyMappingPolicy
{
private readonly Type _typeFrom;
private readonly Type _typeTo;
public MapBuildKeyToDefaultPolicy(Type typeFrom, Type typeTo)
{
this._typeFrom = typeFrom;
this._typeTo = typeTo;
}
public NamedTypeBuildKey Map(NamedTypeBuildKey buildKey, IBuilderContext context)
{
if (buildKey.Type == this._typeFrom)
return new NamedTypeBuildKey(this._typeTo);
throw new InvalidOperationException();
}
}
测试类:
public interface IFoo
{
void Bar();
}
public class FooNamed : IFoo
{
public void Bar()
{
Console.WriteLine("named one");
}
}
public class FooDefault : IFoo
{
public void Bar()
{
Console.WriteLine("default one");
}
}
测试:
public static class Program
{
static void Main(string[] args)
{
var container = new UnityContainer();
// register extension before use container!
container.AddExtension(new DefaultRegistrationFallbackConfiguration());
container.RegisterType(typeof(IFoo), typeof(FooDefault));
container.RegisterType(typeof(IFoo), typeof(FooNamed), "named");
container.Resolve<IFoo>() .Bar(); // default one
container.Resolve<IFoo>("named") .Bar(); // named one
container.Resolve<IFoo>("unknown").Bar(); // default one
}
}
输出:
默认一个 命名为一 默认一个