StructureMap 指定显式构造函数参数
我正在处理遗留代码。
我有同一个类的不同方法,它们将不同的参数传递给依赖项的构造函数。我正在尝试介绍一些基本的 IoC 用法。现在,我有 StructureMap 传递我的参数,如下所示:
var thing = ObjectFactory.GetInstance<IThingInterface>(new ExplicitArguments(
new Dictionary<string, object> {
{ "constructorArgA", notShown },
{ "constructorArgB", redacted.Property } }));
构造函数 ArgA 和 B 传递的实际属性根据我所在的位置而变化。
有一种方法可以通过实际类型来配置它,而不是“constructorArgA”,就像配置 objectFactory 时可以做的那样:
x.For<IHidden>().Use<RealType>()
.Ctor<IConfig>().Is(new Func<IContext, IConfig>(
(context) => someMethodToGetIConfig()));
如果我从头开始编写这个,我可能会构建有点不同的依赖关系以避免这种情况,但那就是现在对我来说不是一个选择。
I'm working on legacy code.
I have different methods of the same class that pass different arguments to the constructor of a dependency. I'm trying to get some basic IoC usage introduced. Right now I have StructureMap passing my arguments like this:
var thing = ObjectFactory.GetInstance<IThingInterface>(new ExplicitArguments(
new Dictionary<string, object> {
{ "constructorArgA", notShown },
{ "constructorArgB", redacted.Property } }));
Where the actual properties passed for constructorArgA and B change depending on where I am.
Instead of "constructorArgA" is there a way to configure this via actual types, like you can do when configuring the objectFactory, like:
x.For<IHidden>().Use<RealType>()
.Ctor<IConfig>().Is(new Func<IContext, IConfig>(
(context) => someMethodToGetIConfig()));
If I were writing this from scratch I'd probably structure the dependencies a bit different to avoid this, but that's not an option for me right now.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是 DI 容器的一个经典/常见问题。
我的第一个选择是创建一个“手动”抽象工厂来创建 IThingInterface,然后使用 Structuremap 在需要的地方注入 IThingInterfaceFactory。通过手动工厂,我的意思是一个调用 new ThingInterface() 并返回它的类。如果您这样做,您的实现将不再由容器管理,并且如果它具有依赖项,则容器将不再提供它们(对您来说可能是问题,也可能不是问题) 。
第二个选择是创建一个实际使用/包装容器的抽象工厂。因此,基本上是您的第一个代码片段,但包装在一个工厂类中,其中 Create() 方法获取您的参数。这样做的优点是所有内容(包括您的实现及其依赖项)都由容器管理,但缺点是直接引用容器(这不是最佳实践 - 请参阅关于组合根的文章)。
您也可以进行 setter 注入,但我个人认为这是最后的手段。
温莎城堡内置了一个很好的解决方案来解决这个问题(类型工厂设施)。不确定是否可以在选项中切换容器,但您可能会考虑它。
This is something of a classic/common question with DI Containers.
My first choice would be to create a "manual" abstract factory to create IThingInterface, and then use Structuremap to inject IThingInterfaceFactory where it is needed. By manual factory, I mean a class the calls new ThingInterface() and returns it. If you do it this way, your implementation will no longer be container-managed, and if it has dependencies, they would no longer be provided by the container (may or may not be a problem for you).
Second choice would be to create an abstract factory that actually uses/wraps the container. So basically your first code snippet but wrapped in a factory class where the Create() method takes your parameters. This has the advantage of everything (including your implementation and its dependencies) being container-managed, but the disadvantage of referencing your container directly (which is not a best practice--see Article on Composition Roots).
You could also do setter injection, but I would personally consider it a last resort.
Castle Windsor has a good solution to this problem built in (Typed Factory Facility). Not sure if switching containers in an option, but you might consider it.