如上所述,Unity 只解析请求的类型,它不查找继承的类或接口。
有一种方法可以将 Unity 与多态解析一起使用,但如果您实现一个使用反射来查找您所追求的实现的 UnityExtension。我们需要一个 Rebus 适配器来实现具有多态功能和方法 Register<> 和 Handle<> 的统一性。
这是我们使用 Unity 的 Rebus 版本,效果很好。
公共类 UnityContainerAdapter:IContainerAdapter,IDisposable {
公共 IBus 总线 { 获取;内部集;}
private readonly IUnityContainer _unityContainer;
private readonly IHandlerRegistrator _handlerRegistrator;
public UnityContainerAdapter(IUnityContainer unityContainer)
{
_unityContainer = unityContainer;
_handlerRegistrator = _unityContainer
.AddNewExtension<AllThatImplements>()
.Configure<IHandlerRegistrator>();
}
public IEnumerable<IHandleMessages> GetHandlerInstancesFor<T>()
{
return _unityContainer.ResolveAll<IHandleMessages<T>>();
}
public void Release(IEnumerable handlerInstances)
{
foreach (IDisposable disposable in handlerInstances.OfType<IDisposable>())
disposable.Dispose();
}
public void SaveBusInstances(IBus bus)
{
Bus = bus;
_unityContainer.RegisterInstance(typeof(IBus), bus);
_unityContainer.RegisterType<IMessageContext>(new InjectionMember[1]
{
new InjectionFactory(c => (object) MessageContext.GetCurrent())
});
}
public UnityContainerAdapter Register<THandler>()
{
_handlerRegistrator.RegisterImplementingType<THandler>(typeof(IHandleMessages<>));
return this;
}
public UnityContainerAdapter Handle<TMessage>(Action<TMessage> handler)
{
_unityContainer.RegisterType<IHandleMessages<TMessage>, HandlerMethodWrapper<TMessage>>(Guid.NewGuid().ToString(), new InjectionConstructor(handler));
return this;
}
internal class HandlerMethodWrapper<T> : IHandleMessages<T>
{
private readonly Action<T> _action;
public HandlerMethodWrapper(Action<T> action)
{
_action = action;
}
public void Handle(T message)
{
_action(message);
}
}
public void Dispose()
{
_unityContainer.Dispose();
}
#region - Unity Extionsion -
internal class AllThatImplements : UnityContainerExtension, IHandlerRegistrator
{
protected override void Initialize() { }
public void RegisterImplementingType<T>(Type implementationToLookFor)
{
var closedType = typeof(T);
closedType.GetInterfaces()
.Where(x => x.IsGenericType)
.Where(x => x.GetGenericTypeDefinition() == implementationToLookFor)
.ToList()
.ForEach(x => Container.RegisterType(x, closedType, Guid.NewGuid().ToString()));
}
}
internal interface IHandlerRegistrator : IUnityContainerExtensionConfigurator
{
void RegisterImplementingType<T>(Type inheritedTypeToLookFor);
}
#endregion
}