autofac 解析所有 ICommandHandler<ICommand,IMessageResult>
autofac resolve all ICommandHandler<ICommand,IMessageResult>
您好,在 .Net 中的 MessageDispatch 场景中,我注册了我所有的命令处理程序,如下所示:
builder.RegisterAssemblyTypes(commandsAssemblies)
.AsClosedTypesOf(typeof(ICommandHandler<,>))
.InstancePerRequest();
在我的 messageDispatcher 的 OnActivating 方法中,我想像这样用 messageDispatcher 注册 commandHandlers。
builder.RegisterType<MessageDispatcher>()
.As<IMessageDispatcher>().InstancePerRequest()
.OnActivating(e =>
{
var handlers = e.Context.Resolve(IEnumerable<ICommandHandler<ICommand,IMessageResult>>);
foreach (var handler in handlers)
{
e.Instance.RegisterCommandHandler(handler);
}
......
commandHandler 的实现方式如下:
public class ActivateCampaignHandler : CommandHandler<ActivateCampaign,MessageResult>
{
....
我的问题是 Resolve 不起作用。我可以看到处理程序已注册,但它自己和 ICommandHandler 只有 2 个服务
如何解决我所有的命令处理程序?
我可以看到 3 个检索 IEnumerable<ICommandHandler<,>>
的解决方案。
最简单的方法是引入一个非通用的 ICommandHandler
接口:
public interface ICommandHandler { }
public interface ICommandHandler<TCommand, TMessageResult>
: ICommandHandler
where TCommand : ICommand
where TMessageResult : IMessageResult
{ }
// register it this way
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
.AsClosedTypesOf(typeof(ICommandHandler<,>))
.As<ICommandHandler>();
这是我推荐的解决方案,因为使用非通用接口可能更容易。
第二种解决方案包括使您的接口协变(使用 out
修饰符)以允许从 TestCommandHandler
转换为 ICommandHandler<ICommand, IMessageResult>
并将您的类型注册为 ICommandHandler<ICommand, IMessageResult>
public interface ICommandHandler<out TCommand, out TMessageResult>
where TCommand : ICommand
where TMessageResult : IMessageResult
{ }
// register this way
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
.AsClosedTypesOf(typeof(ICommandHandler<,>))
.As<ICommandHandler<ICommand, IMessageResult>>();
// resolve this ways
var commandHandlers = container.Resolve<IEnumerable<ICommandHandler<ICommand, IMessageResult>>>();
Console.WriteLine(commandHandlers.Count());
最新的解决方案是创建你自己的 IRegistrationSource
它需要更多的工作,但它会避免将你的类型注册为 ICommandHandler<ICommand, IMessageResult>
并允许你解决类似的问题 ICommandHandler<ISpecificCommand, IMessageResult>
(如果你 IRegistrationSource
实现当然允许)。
您可以查看 ContravariantRegistrationSource
了解如何制作您的。
您好,在 .Net 中的 MessageDispatch 场景中,我注册了我所有的命令处理程序,如下所示:
builder.RegisterAssemblyTypes(commandsAssemblies)
.AsClosedTypesOf(typeof(ICommandHandler<,>))
.InstancePerRequest();
在我的 messageDispatcher 的 OnActivating 方法中,我想像这样用 messageDispatcher 注册 commandHandlers。
builder.RegisterType<MessageDispatcher>()
.As<IMessageDispatcher>().InstancePerRequest()
.OnActivating(e =>
{
var handlers = e.Context.Resolve(IEnumerable<ICommandHandler<ICommand,IMessageResult>>);
foreach (var handler in handlers)
{
e.Instance.RegisterCommandHandler(handler);
}
......
commandHandler 的实现方式如下:
public class ActivateCampaignHandler : CommandHandler<ActivateCampaign,MessageResult>
{
....
我的问题是 Resolve 不起作用。我可以看到处理程序已注册,但它自己和 ICommandHandler 只有 2 个服务
如何解决我所有的命令处理程序?
我可以看到 3 个检索 IEnumerable<ICommandHandler<,>>
的解决方案。
最简单的方法是引入一个非通用的 ICommandHandler
接口:
public interface ICommandHandler { }
public interface ICommandHandler<TCommand, TMessageResult>
: ICommandHandler
where TCommand : ICommand
where TMessageResult : IMessageResult
{ }
// register it this way
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
.AsClosedTypesOf(typeof(ICommandHandler<,>))
.As<ICommandHandler>();
这是我推荐的解决方案,因为使用非通用接口可能更容易。
第二种解决方案包括使您的接口协变(使用 out
修饰符)以允许从 TestCommandHandler
转换为 ICommandHandler<ICommand, IMessageResult>
并将您的类型注册为 ICommandHandler<ICommand, IMessageResult>
public interface ICommandHandler<out TCommand, out TMessageResult>
where TCommand : ICommand
where TMessageResult : IMessageResult
{ }
// register this way
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
.AsClosedTypesOf(typeof(ICommandHandler<,>))
.As<ICommandHandler<ICommand, IMessageResult>>();
// resolve this ways
var commandHandlers = container.Resolve<IEnumerable<ICommandHandler<ICommand, IMessageResult>>>();
Console.WriteLine(commandHandlers.Count());
最新的解决方案是创建你自己的 IRegistrationSource
它需要更多的工作,但它会避免将你的类型注册为 ICommandHandler<ICommand, IMessageResult>
并允许你解决类似的问题 ICommandHandler<ISpecificCommand, IMessageResult>
(如果你 IRegistrationSource
实现当然允许)。
您可以查看 ContravariantRegistrationSource
了解如何制作您的。