Bre*_*ias 18 .net c# dependency-injection ioc-container strategy-pattern
关于这个话题的讨论很多,但每个人似乎都错过了一个明显的答案.我想帮助审查这个"明显的"IOC容器解决方案.各种对话假设运行时选择策略和使用IOC容器.我将继续这些假设.
我还想补充一个假设,即它不是必须选择的单一策略.相反,我可能需要检索一个对象图,该对象图在整个图的节点中找到了几个策略.
我将首先快速概述两个常用的解决方案,然后我将展示我希望看到IOC容器支持的"明显"替代方案.我将使用Unity作为示例语法,但我的问题不是Unity特有的.
这种方法要求每个新策略都手动添加绑定:
Container.RegisterType<IDataAccess, DefaultAccessor>();
Container.RegisterType<IDataAccess, AlphaAccessor>("Alpha");
Container.RegisterType<IDataAccess, BetaAccessor>("Beta");
Run Code Online (Sandbox Code Playgroud)
......然后明确要求正确的策略:
var strategy = Container.Resolve<IDataAccess>("Alpha");
Run Code Online (Sandbox Code Playgroud)
为了说明这种方法,假设以下类:
public class DataAccessFactory{
public IDataAccess Create(string strategy){
return //insert appropriate creation logic here.
}
public IDataAccess Create(){
return //Choose strategy through ambient context, such as thread-local-storage.
}
}
public class Consumer
{
public Consumer(DataAccessFactory datafactory)
{
//variation #1. Not sufficient to meet requirements.
var myDataStrategy = datafactory.Create("Alpha");
//variation #2. This is sufficient for requirements.
var myDataStrategy = datafactory.Create();
}
}
Run Code Online (Sandbox Code Playgroud)
然后IOC容器具有以下绑定:
Container.RegisterType<DataAccessFactory>();
Run Code Online (Sandbox Code Playgroud)
这是我想要使用的方法而不是上述两种方法.它涉及提供委托作为IOC容器绑定的一部分.大多数IOC容器都具备此功能,但这种特定方法具有重要的细微差别.
语法如下:
Container.RegisterType(typeof(IDataAccess),
new InjectionStrategy((c) =>
{
//Access ambient context (perhaps thread-local-storage) to determine
//the type of the strategy...
Type selectedStrategy = ...;
return selectedStrategy;
})
);
Run Code Online (Sandbox Code Playgroud)
请注意,InjectionStrategy是不是返回的一个实例IDataAccess.相反,它返回一个实现的类型描述IDataAccess.然后,IOC容器将执行该类型的常规创建和"构建",其可能包括选择的其他策略.
这与标准的类型到委托绑定形成对比,在Unity的情况下,它的编码如下:
Container.RegisterType(typeof(IDataAccess),
new InjectionFactory((c) =>
{
//Access ambient context (perhaps thread-local-storage) to determine
//the type of the strategy...
IDataAccess instanceOfSelectedStrategy = ...;
return instanceOfSelectedStrategy;
})
);
Run Code Online (Sandbox Code Playgroud)
上述实际上接近满足整体需求,但绝对不能满足假设的Unity InjectionStrategy.
专注于第一个样本(使用假设的Unity InjectionStrategy):
Type创建初始IOC容器绑定时策略返回的结果不可用,这意味着第一次返回该类型时可能会遇到微小的性能损失.换句话说,容器必须在现场反映类型以发现它具有的构造函数,以便它知道如何注入它.该类型的所有后续出现都应该很快,因为容器可以缓存第一次找到的结果.这不是一个值得一提的"骗局",但我正在努力进行全面披露.是否存在可以以这种方式运行的现有IOC容器?任何人都有Unity自定义注入类来实现这种效果?
Mar*_*ann 16
据我所知,这个问题是关于运行时选择或几个候选策略之一的映射.
没有理由依赖DI容器来执行此操作,因为至少有三种方法可以以容器无关的方式执行此操作:
我个人的偏好是部分类型名称角色提示.