我刚刚学会了如何在上周进行注射,这就是我目前如何设置注意事项:
using Ninject;
using System.Reflection;
namespace Infrastructure
{
public static class Inject<T>
{
static bool b = Bootstrap();
static IKernel kernel;
static bool Bootstrap()
{
kernel = new StandardKernel();
kernel.Load(Assembly.GetExecutingAssembly());
return true;
}
public static T New() { return kernel.Get<T>(); }
}
}
然后我计划将各种ninject模块类作为Infrastructure命名空间的一部分,以便加载它们。
我无法在这里或Google上找到任何有关如何在项目中实际组织Ninject使用的示例,但这对我来说似乎是正确的,因为它允许我只需要Ninject参考部件。这或多或少是“正确的”方式还是有更好的设计?
答案 0 :(得分:4)
现在你做的事情有一些问题。
首先让我从明显的C#问题开始:泛型类中的静态类变量是基于T
共享的。换句话说,Inject<IUserRepository>
和Inject<IOrderRepository>
将各自获得自己的IKernel
实例,这不太可能是您真正想要的,因为您很可能只需要一个IKernel
申请的有效期。如果您没有单独的IKernel
应用程序,则无法将类型注册为singleton,因为singleton始终在容器级别进行范围设定,而不是在应用程序级别。因此,您最好将类重写为非泛型,并将泛型类型参数移动到方法中:
Inject.New<T>()
第二个问题是涉及依赖注入。在我看来,您正在尝试使用Service Locator anti-pattern,因为您可能在应用程序中明确地调用了Inject.New<T>
。 DI容器只应在应用程序的启动路径中引用,并且应该能够构建相关对象的完整对象图。这样,您可以要求容器为您获取根级对象(例如MVC上下文中的Controller
),并且应用程序的其余部分将无视任何DI技术的使用。执行此操作时,无需抽象使用容器(就像使用Inject
类一样)。
并非所有应用程序或UI技术都允许此BTW。在使用Web窗体应用程序时,我倾向于隐藏我的容器(就像你正在做的那样),因为不可能对Page
类,IHttpHandler
对象和{{1}进行适当的依赖注入} class。