nie*_*ras 6 c# structuremap ninject ioc-container autofac
这可能只是一个新手问题,但我有以下几点:
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) { ... }
}
Run Code Online (Sandbox Code Playgroud)
FooSettings或BarSettings的实例由外部源提供,即:
object settings = GetSettings();
Run Code Online (Sandbox Code Playgroud)
现在我想基于注入现有的设置实例来解决ProcessorConsumer,例如:
container.RegisterAssemblyTypes(...); // Or similar
container.Inject(settings);
var consumer = container.Resolve<IProcessorConsumer>();
Run Code Online (Sandbox Code Playgroud)
也就是说,如果提供了FooSettings的实例,则创建FooProcessor并将其注入ProcessorConsumer,然后解析实例.
我无法在StructureMap,Ninject和Autofac中弄清楚如何做到这一点......可能是因为我是IoC容器的新手.因此,所有这些或其他容器的答案,以便他们可以比较将非常感激.
更新:我正在寻找一种可以轻松添加新设置和处理器的解决方案.此外,还有从设置类型到处理器类型的一对一映射.但是,它还允许基于其构造函数参数在给定的处理器类型中注入其他实例/服务.即某些处理器可能需要IResourceProvider服务或类似服务.这里只是一个例子.
理想情况下,我想要像
container.For<IProcessor>.InjectConstructorParameter(settings)
Run Code Online (Sandbox Code Playgroud)
或类似的.因此,指导IoC容器使用与注入的构造函数参数实例匹配的处理器类型.
你不希望这种依赖注入.你想要一个工厂(当然,你可以用你的容器建造).工厂会知道如何采取,IProcessorSettings并返回适当的IProcessor.简而言之,您可以构建一个工厂,该工厂使用实现的对象的具体类型IProcessorSettings和容器来解析相应类型的实例.
我认为您正在寻找的是ForObject()StructureMap 中的方法。它可以根据给定的对象实例关闭开放的泛型类型。您需要对设计进行的关键更改是引入泛型类型:
public interface IProcessor { }
public interface IProcessor<TSettings> : IProcessor{}
Run Code Online (Sandbox Code Playgroud)
所有重要的东西仍然在 上声明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) { }
}
Run Code Online (Sandbox Code Playgroud)
现在,给定一个设置对象的实例,您可以检索正确的IProcessor:
IProcessor processor = container.ForObject(settings).
GetClosedTypeOf(typeof(IProcessor<>)).
As<IProcessor>();
Run Code Online (Sandbox Code Playgroud)
现在,您可以告诉 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>();
});
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1584 次 |
| 最近记录: |