ICommandHandler的问题<icommand <tentity>&gt;登记

时间:2017-05-10 00:55:33

标签: c# asp.net-mvc simple-injector

我有这样的命令接口:

public interface ICommand { }

public interface ICommand<in TEntity> : ICommand { }

public interface ICommandHandler<in TCommand> where TCommand : class, ICommand
{
    void Handle(TCommand command);
}

我的一个通用命令如下:

    public class ChangeCommand<TEntity> : ICommand<TEntity> where TEntity : class, IEntity
{
    public TEntity entityToChange { get; set; }
}

我使用的是最新版本的SimpleInjector。我的商家配置如下:

public class BusinessLayerBootstrapper
{
    public static void Bootstrap(Container container)
    {
        if(container == null)
        {
            throw new ArgumentNullException("BusinessLayerBootstrapper container");
        }

        container.RegisterSingleton<IValidator>(new DataAnnotationsValidator(container));

        var typesToRegister = container.GetTypesToRegister(typeof(ICommandHandler<>),
            AppDomain.CurrentDomain.GetAssemblies(),
            new TypesToRegisterOptions
            {
                IncludeGenericTypeDefinitions = true,
                IncludeDecorators = false,
                IncludeComposites = false
            });
        container.RegisterCollection(typeof(ICommandHandler<>), typesToRegister);

        container.RegisterDecorator(typeof(ICommandHandler<>), typeof(PostCommitCommandHandlerDecorator<>));

        container.Register<IPostCommitRegistrator>(() => container.GetInstance<PostCommitRegistrator>(), Lifestyle.Scoped);

        container.RegisterDecorator(typeof(ICommandHandler<>), typeof(TransactionCommandHandlerDecorator<>));
        container.RegisterDecorator(typeof(ICommandHandler<>), typeof(ValidationCommandHandlerDecorator<>));
        container.RegisterDecorator(typeof(ICommandHandler<>), typeof(AuthorizationCommandHandlerDecorator<>));

        container.Register(typeof(IQueryHandler<,>), AppDomain.CurrentDomain.GetAssemblies());
        container.RegisterDecorator(typeof(IQueryHandler<,>), typeof(AuthorizationQueryHandlerDecorator<,>));
    }
}

ASP.NET MVC配置:

public class Bootstrapper
{
    public static void Bootstrap()
    {
        Container container = new Container();
        container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();

        Business.BusinessLayerBootstrapper.Bootstrap(container);

        container.Register<IPrincipal>(() => HttpContext.Current.User ?? Thread.CurrentPrincipal);

        container.RegisterSingleton<ILogger>(new FileLogger());

        container.Register<IUnitOfWork>(() => new UnitOfWork(ConfigurationManager.ConnectionStrings["PriceMonitorMSSQLConnection"].ConnectionString), Lifestyle.Scoped);

        container.RegisterMvcControllers(Assembly.GetExecutingAssembly());

        container.Verify(VerificationOption.VerifyAndDiagnose);

        DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
    }
}

在控制器中我有这样的代码:

public class HomeController : Controller
{
    ICommandHandler<ICommand<Product>>                                                      CreateProduct;
    ICommandHandler<ICommand<Product>>                                                      ChangeProduct;
    ICommandHandler<ICommand<Product>>                                                      DeleteProduct;
    ICommandHandler<ChangeProductWpriceCommand>                                             ChangeProductWprice;
    IQueryHandler<ProdStoreHierByUserQuery, IEnumerable<ProductStoreHierarchy>>             PSTree;
    IQueryHandler<ProdStoreStatByProdIdUserPeriodQuery, IEnumerable<ProductStoreStatistic>> Statistic;

    public HomeController(ICommandHandler<ICommand<Product>> CreateProduct,
                          ICommandHandler<ICommand<Product>> ChangeProduct,
                          ICommandHandler<ICommand<Product>> DeleteProduct,
                          ICommandHandler<ChangeProductWpriceCommand> ChangeProductWprice,
                          IQueryHandler<ProdStoreHierByUserQuery, IEnumerable<ProductStoreHierarchy>> PSTree,
                          IQueryHandler<ProdStoreStatByProdIdUserPeriodQuery, IEnumerable<ProductStoreStatistic>> Statistic)
    {
        this.CreateProduct       =  CreateProduct;
        this.ChangeProduct       =  ChangeProduct;
        this.DeleteProduct       =  DeleteProduct;
        this.ChangeProductWprice =  ChangeProductWprice;
        this.PSTree              =  PSTree;
        this.Statistic           =  Statistic;
    }

    // some actions...

}

结果container.Verify方法抛出异常:

  

类型&#39; System.InvalidOperationException&#39;的例外情况发生在SimpleInjector.dll中但未在用户代码中处理

     

其他信息:配置无效。为类型HomeController创建实例失败。 HomeController类型的构造函数包含名称为&#39; CreateProduct&#39;的参数。并输入ICommandHandler&lt; ICommand&lt; Product&gt;&gt;那是没有注册的。请确保已注册ICommandHandler<ICommand<Product>>,或更改HomeController的构造函数。但是,有IEnumerable<ICommandHandler<ICommand<Product>>>的注册;您的意思是依赖IEnumerable<ICommandHandler<ICommand<Product>>>吗?

如果我不使用RegisterCollection方法,则会抛出相同的异常。能否请你给我一个如何解决这个问题的建议?

已更新

根据史蒂文的评论,我根据给定的建议编辑了我的问题。我现在注册的是:

//container.RegisterCollection(typeof(ICommandHandler<>), typesToRegister);
// is replaced with
container.Register(typeof(ICommandHandler<>), typesToRegister);
// ...

Register抛出异常:

  

提供的类型列表包含一个或多个开放泛型类型,但此方法无法处理开放泛型类型,因为它只能将封闭的通用服务类型映射到单个实现。请尝试使用RegisterCollection。无效类型:ChangeCommandHandler&lt; TEntity&gt;,CreateCommandHandler&lt; TEntity&gt;和DeleteCommandHandler&lt; TEntity&gt;。   参数名称:implementationTypes

如果我将以前的代码留给第一个变体,但会将我的控制器更改为:

    ICommandHandler<CreateCommand<Product>> CreateProduct;
    ICommandHandler<ChangeCommand<Product>> ChangeProduct;
    ICommandHandler<DeleteCommand<Product>> DeleteProduct;
    ICommandHandler<ChangeProductWpriceCommand>                                             ChangeProductWprice;
    IQueryHandler<ProdStoreHierByUserQuery, IEnumerable<ProductStoreHierarchy>>             PSTree;
    IQueryHandler<ProdStoreStatByProdIdUserPeriodQuery, IEnumerable<ProductStoreStatistic>> Statistic;

    public HomeController(ICommandHandler<CreateCommand<Product>> CreateProduct,
                          ICommandHandler<ChangeCommand<Product>> ChangeProduct,
                          ICommandHandler<DeleteCommand<Product>> DeleteProduct,
                          ICommandHandler<ChangeProductWpriceCommand> ChangeProductWprice,
                          IQueryHandler<ProdStoreHierByUserQuery, IEnumerable<ProductStoreHierarchy>> PSTree,
                          IQueryHandler<ProdStoreStatByProdIdUserPeriodQuery, IEnumerable<ProductStoreStatistic>> Statistic)
    {
        this.CreateProduct = CreateProduct;
        this.ChangeProduct = ChangeProduct;
        this.DeleteProduct = DeleteProduct;
        this.ChangeProductWprice = ChangeProductWprice;
        this.PSTree = PSTree;
        this.Statistic = Statistic;
    }

然后Verify方法抛出类似于第一个的异常:

  

配置无效。为类型HomeController创建实例失败。 HomeController类型的构造函数包含名称为&#39; CreateProduct&#39;的参数。并键入ICommandHandler&lt; CreateCommand&lt; Product&gt;&gt;那是没有注册的。请确保ICommandHandler&lt; CreateCommand&lt; Product&gt;&gt;已注册,或更改HomeController的构造函数。但是,IEnumerable&lt; ICommandHandler&lt; CreateCommand&lt; Product&gt;&gt;&gt;的注册;你的意思是依赖于IEnumerable&lt; ICommandHandler&lt; CreateCommand&lt; Product&gt;&gt;&gt;?

也许您可以通过Repository模式向我提供如何解决此问题的建议?

0 个答案:

没有答案