StructureMap StructureMap.StructureMapBuildPlanException,避免使用ObjectFactory

时间:2018-08-03 06:53:09

标签: c# winforms structuremap cqrs

我偶然发现使用StructureMap https://www.codeproject.com/Articles/555855/Introduction-to-CQRS

的CQRS示例

但是,有示例使用ObjectFactory,但我想避免这种情况。

var cmdHandler = handlers.Select(handler => 
    (ICommandHandler<T>)ObjectFactory.GetInstance(handler)).FirstOrDefault();

可以在https://www.codeproject.com/script/Articles/ViewDownloads.aspx?aid=555855-> Utils-> StructureMapCommandHandlerFactory.cs中找到此代码

我想在WinForms上尝试此示例,但不使用ObjectFactory。 不幸的是,我得到一个例外:

  

类型的未处理异常   “ StructureMap.StructureMapBuildPlanException”发生在   StructureMap.dll

     

其他信息:无法为混凝土创建建造计划   键入CQRS.Core.Commands.CreateItemCommand

我当前的配置是

 private IContainer container;

 public StructureMapCommandHandlerFactory()
 {
     this.container = new Container(_ => {     
           _.For<ICommandHandler<CreateItemCommand>>().Use<CreateItemCommandHandler>();
           _.Policies.ConstructorSelector<ThingCtorRuleCommand>();
                });
 }



 public class ThingCtorRuleCommand : IConstructorSelector
 {
     public ConstructorInfo Find(Type pluggedType, DependencyCollection dependencies, PluginGraph graph)
     {
         if (!pluggedType.CanBeCastTo<Command>()) return null;
          var ctr = pluggedType.GetConstructor(new[] { typeof(IRepository<DiaryItem>) });
         return ctr;
     }
 }


public class CreateItemCommandHandler : ICommandHandler<CreateItemCommand>
{
    private IRepository<DiaryItem> _repository;

    public CreateItemCommandHandler(IRepository<DiaryItem> repository)
    {
         _repository = repository;
    }

    public void Execute(CreateItemCommand command)
    {
           ...
    }
}

和对象实例化:

var cmdHandler = container.GetInstance<CreateItemCommand>();

问题: 1.如何配置结构图以获取对象CreateItemCommandHandler? 2.我不太了解如何使用值实例化对象? 这里描述了将简单的参数传递给构造函数: http://structuremap.github.io/resolving/passing-arguments-at-runtime/

但是如何将存储库对象传递给

public CreateItemCommandHandler(IRepository<DiaryItem> repository)
{
     _repository = repository;
}

我希望有人能帮助我...

编辑:

经过一番调查,我发现了错误。将容器配置更改为此:

    private IContainer container;

     public StructureMapCommandHandlerFactory()
     {
                _.For<ICommand>().Use<Command>();
                _.For<ICommandHandler<CreateItemCommand>>().Use<CreateItemCommandHandler>();
                _.For<IRepository<DiaryItem>>().Use(new Repository<DiaryItem>());
                _.Policies.ConstructorSelector<ThingCtorRuleCommand>();
     }

和对象实例化:

var cmdHandler = container.GetInstance<CreateItemCommandHandler>();

有效。

但是,我仍然不太了解如何在初始化时将值传递给构造函数。 由于ObjectFactory已过时,因此我的解决方案是正确的,还是偶然解决的方案? :)

编辑2

我弄清楚了如何设置参数:

EventBus eventBus = new EventBus(new StructureMapEventHandlerFactory());
IEventStorage storage = new InMemoryEventStorage(eventBus);
Repository<DiaryItem> repository = new Repository<DiaryItem>(storage);

var cmdHandler = container.With<IRepository<DiaryItem>>(repository).With<IEventStorage>(storage).GetInstance<ICommandHandler<CreateItemCommand>>();

所以

With<IRepository<DiaryItem>>(repository).With<IEventStorage>(storage) 

可以解决问题。

此处有更多相关信息:http://structuremap.github.io/resolving/passing-arguments-at-runtime/

还有一个问题我还没有回答自己:由于ObjectFactory已过时,它是我的解决方案正确的方法,还是只是偶然解决的方法? :),请帮助...

0 个答案:

没有答案