Den*_*oli 6 dependency-injection ninject
开始我正在使用Ninject 1.5.我有两个项目:Web项目和类库.我的DI配置在Web项目中.在我的类库中,我定义了以下内容:
public interface ICacheService<T>
{
string Identifier { get; }
T Get();
void Set( T objectToCache, TimeSpan timeSpan );
bool Exists();
}
Run Code Online (Sandbox Code Playgroud)
然后是一个名为CategoryCacheService的具体类.
在我的web项目中,我绑定了两个:
Bind( typeof( ICacheService<List<Category>> ) ).To( typeof(CategoryCacheService)).Using<SingletonBehavior>();
Run Code Online (Sandbox Code Playgroud)
在我的类库中,我有HtmlHelper类的扩展方法,例如:
public static class Category
{
[Inject]
public static ICacheService<List<Category>> Categories { get; set; }
public static string RenderCategories(this HtmlHelper htmlHelper)
{
var c = Categories.Get();
return string.Join(", ", c.Select(s => s.Name).ToArray());
}
}
Run Code Online (Sandbox Code Playgroud)
我被告知你不能注入静态属性,而是我应该使用Kernel.Get <>() - 但是......由于上面的代码在类库中,我无法访问内核.如何从这一点获取内核,或者有更好的方法吗?
好问题.
使用DI的一半想法是从注入代码中删除对实例化行为的关注/微调.因此,将Category类更改为不再是更有意义,static在ctor中声明其依赖关系并让客户端代码将它们拼接在一起.
关于如何访问它,如果你真的确定它是一个好主意...通常你的情况下的想法是创建一个CacheServiceResolver并在[你的Web项目]注册它.然后将Kernel实例传递给它.这样你的DLL只绑定到你的接口CacheServiceResolver.
通常使用的另一种方法是在全球某处设置最后的"服务定位器"设施,从而暴露出"GlobalGet".但这通常是一个坏主意,应该只用于临时管道编带目的.
要看的另一件事是Common Service Locator,它允许一个库容器中立,虽然在EL之外,你不会发现很多用法,因为你不应该真正展示你的容器.
另一个选择是要求一个Func<T>工厂方法,并将Bind其解析为解析它的lambda,从代码中提取该查找.
编辑:在Ninject 2中,没有必要Kernel像我所说的那样明确地传递实例 - 你可以简单地IKernel在你的ctor中询问一个并且你会得到它,无论解析请求是否明确地通过了一个.
编辑2:对我的回答真的不满意,试图让它更普遍,而不是过多地屠杀它.总结是,理想的选项通常按顺序排列如下:
| 归档时间: |
|
| 查看次数: |
5126 次 |
| 最近记录: |