简体   繁体   中英

StructureMap Open Generic types with multiple types

so I've been trying to solve this issue for a couple of hours now. I searched the internet and looked at many Stackoverflow questions, but none could help me.


So I'm building a pipeline. The basic conecpt is the following:

  • PipelineStore (Singleton) - Contains all registered Pipeline
  • Pipeline[TEntity] (Transient) - One Pipeline per Entity (Account, Contact, ...)
  • PipelineStep[TOperation, TInteractor, TEntity] (Transient) - Many Steps per Pipeline

[] representing the generic types.


I want to use StructureMap to create the Pipeline and the PipelineStep. So I created an auto factory called IPipelineFactory which has a single function:

IPipeline<TEntity> CreatePipeline<TEntity>() TEntity : EntityDTO, new();

I registered it in the Registry:

For<IPipelineFactory>().CreateFactory();
For(typeof(IPipeline<>))
    .Use(typeof(Pipeline<>))
    .Transient();

Then I get the IPipelineFactory injected and use it like the following:

public IPipeline<TEntity> NewPipeline<TEntity>() 
    where TEntity : EntityDTO, new()
{
    var pipeline = _pipelineFactory.CreatePipeline<TEntity>();
    _pipelines.Add(pipeline);
    return pipeline;
}

This works great, but when I try to do the same thing with the PipelineStep it fails:

public interface IPipelineStepFactory
{
    IPipelineStep<TOperation, TInteractor, TEntity> CreatePipelineStep<TOperation, TInteractor, TEntity>() 
        where TOperation : IOperation<TInteractor, TEntity> 
        where TInteractor : IInteractor<TEntity>
        where TEntity : EntityDTO, new();
}

And the registration:

For<IPipelineStepFactory>().CreateFactory();
For(typeof(IPipelineStep<,,>))
    .Use(typeof(PipelineStep<,,>));

usage:

public IAddPipeline<TEntity> Pipe<TOperation, TInteractor>()
    where TOperation : IOperation<TInteractor, TEntity>
    where TInteractor : IInteractor<TEntity>
{
    var step = PipelineStepFactory.CreatePipelineStep<TOperation, TInteractor, TEntity>();
    RegisteredSteps.Add(step);
    return this;
}

When I try to test the code it throws the following exception at runtime:

No default Instance is registered and cannot be automatically determined for type 'IPipelineStep<TestOperation, ITestInteractor, TestEntity>'

There is no configuration specified for IPipelineStep<TestOperation, ITestInteractor, TestEntity>

I thinks it's probably missing support for open generic types with multiple type arguments. Please let me know if there's any workarround to fix this issue. Thanks for your time!

So I figured it out myself. The problem was, that the PipelineStep had slightly different generic type constraints which caused the issue. I changed

public class PipelineStep<TOperation, TInteractor, TEntity> : PipelineStepBase, IPipelineStep<TOperation, TInteractor, TEntity> 
    where TOperation : IOperation<TInteractor, TEntity>, IOperation<IInteractor<EntityDTO>, EntityDTO>
    where TInteractor : IInteractor<TEntity>, IInteractor<EntityDTO>
    where TEntity : EntityDTO

to

public class PipelineStep<TOperation, TInteractor, TEntity> : PipelineStepBase, IPipelineStep<TOperation, TInteractor, TEntity> 
        where TOperation : IOperation<TInteractor, TEntity>
        where TInteractor : IInteractor<TEntity>
        where TEntity : EntityDTO

and now it's working!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM