c# – 如何使用现有实例选择要在IoC容器中创建的类型

前端之家收集整理的这篇文章主要介绍了c# – 如何使用现有实例选择要在IoC容器中创建的类型前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
这可能只是一个新手问题,但我有以下几点:
public class FooSettings {}
public class BarSettings {}
public class DohSettings {}
// There might be many more settings types...

public interface IProcessor { ... }

public class FooProcessor
    : IProcessor
{
     public FooProcessor(FooSettings) { ... }
}

public class BarProcessor
    : IProcessor
{
     public BarProcessor(BarSettings) { ... }
}

public class DohProcessor
    : IProcessor
{
     public DohProcessor(DohSettings) { ... }
}

// There might be many more processor types with matching settings...

public interface IProcessorConsumer {}

public class ProcessorConsumer 
    : IProcessorConsumer
{
     public ProcessorConsumer(IProcessor processor) { ... }
}

FooSettings或BarSettings的一个实例是从外部源提供的,即:

object settings = GetSettings();

现在我想基于注入现有的设置实例来解决ProcessorConsumer,例如:

container.RegisterAssemblyTypes(...); // Or similar
container.Inject(settings);
var consumer = container.Resolve<IProcessorConsumer>();

也就是说,如果提供了FooSettings的实例,则创建FooProcessor并将其注入ProcessorConsumer,然后解析实例.

我无法在StructureMap,Ninject和Autofac中弄清楚如何做到这一点……可能是因为我是IoC容器的新手.因此,所有这些或其他容器的答案,以便他们可以比较将非常感激.

更新:我正在寻找一种可以轻松添加新设置和处理器的解决方案.此外,还有从设置类型到处理器类型的一对一映射.但是,它还允许基于其构造函数参数在给定的处理器类型中注入其他实例/服务.即某些处理器可能需要IResourceProvider服务或类似服务.这里只是一个例子.

理想情况下,我想要像

container.For<IProcessor>.InjectConstructorParameter(settings)

或类似的.因此,指导IoC容器使用与注入的构造函数参数实例匹配的处理器类型.

解决方法

我认为你在寻找的是StructureMap中的ForObject()方法.它可以基于给定的对象实例关闭开放的泛型类型.您需要对设计进行的关键更改是引入泛型类型:
public interface IProcessor { }
public interface IProcessor<TSettings> : IProcessor{}

所有重要的东西仍然在IProcessor,通用IProcessor< TSettings>上声明.实际上只是一个标记界面.然后,每个处理器将实现通用接口,以声明它们期望的设置类型:

public class FooProcessor : IProcessor<FooSettings>
{
     public FooProcessor(FooSettings settings) {  }
}

public class BarProcessor : IProcessor<BarSettings>
{
     public BarProcessor(BarSettings settings) {  }
}

public class DohProcessor : IProcessor<DohSettings>
{
     public DohProcessor(DohSettings settings) {  }
}

现在,给定一个设置对象的实例,您可以检索正确的IProcessor:

IProcessor processor = container.ForObject(settings).
  GetClosedTypeOf(typeof(IProcessor<>)).
  As<IProcessor>();

现在,您可以告诉StructureMap在解析IProcessor时使用此逻辑:

var container = new Container(x =>
{
    x.Scan(scan =>
    {
        scan.TheCallingAssembly();
        scan.WithDefaultConventions();
        scan.ConnectImplementationsToTypesClosing(typeof(IProcessor<>));
    });

    x.For<IProcessor>().Use(context =>
    {
        // Get the settings object somehow - I'll assume an ISettingsSource
        var settings = context.GetInstance<ISettingsSource>().GetSettings();
        // Need access to full container,since context interface does not expose ForObject
        var me = context.GetInstance<IContainer>();
        // Get the correct IProcessor based on the settings object
        return me.ForObject(settings).
            GetClosedTypeOf(typeof (IProcessor<>)).
            As<IProcessor>();
    });

});

猜你在找的C#相关文章