我目前在需要使用CustomerBusiness(这是我的服务)的课程中有以下这些,它的工作正常,但我很清楚,这不是推荐的方法.
private CustomerBusiness _customerBusiness;private ICustomerRepository CustomerRepository{ get { return NinjectWebCommon.Kernel.Get<IAccountRepository>(); }}private CustomerBusiness CustomerBusiness{ get { if (_customerBusiness == null) { _customerBusiness = new CustomerBusiness(AccountRepository); } return _customerBusiness; }}public Customer GetCustomer(int ID){ return CustomerBusiness.GetCustomer(ID);}
这是在上面的代码中访问的内核属性:
public static IKernel Kernel{ get { return CreateKernel(); }}
我已经阅读了许多有关使用工厂的建议,但是他们都没有解释如何使用这个工厂.我真的很感激任何人可以向我显示“CustomerFactory”或任何其他建议的方法,包括如何使用它.
更新
我正在使用ASP.NET Web窗体,需要从CodeBehind访问CustomerBusiness.
解
我发现这个工作的最终解决方案是这个帖子中最多的答案:
How can I implement Ninject or DI on asp.net Web Forms?
它看起来像这样(来自PageBase的继承,它是Ninject.Web的一部分 – 这是关键!):
public partial class Edit : PageBase{ [Inject] public ICustomerBusiness CustomerBusiness { get; set; } ...
下面接受的答案间接导致我找到这个解决方案.
解决方法 因为你使用NinjectWebCommon,我假设你有一个Web应用程序.你真的只能在一个地方访问Ninject内核 – 在 composition root.这是你建立对象图的地方,唯一应该需要访问IoC容器的地方.要实际获得您需要的依赖项,您通常使用 constructor injection.例如,在MVC Web应用程序的情况下,您有一个使用Ninject内核的控制器工厂,这是唯一引用它的地方.
为了扩展您的特定情况,您的课程将在其构造函数中接受ICustomerBusiness,声明它需要一个ICustomerBusiness实例作为其依赖关系:
class CustomerBusinessConsumer : ICustomerBusinessConsumer{ private Readonly ICustomerBusiness customerBusiness; public CustomerBusinessConsumer(ICustomerBusiness customerBusiness) { this.customerBusiness = customerBusiness; } ...}
现在,无论哪个类使用ICustomerBusinessConsumer作为其依赖关系,都将遵循相同的模式(接受ICustomerBusinessConsumer的实例作为其构造函数).您基本上从来没有使用新的(特定的例外)手动构建您的依赖关系.
然后,你只需要确保你的类获得它们的依赖关系,这个组合根是你做这个的.组合根究竟取决于您正在编写的应用程序的类型(控制台应用程序,WPF应用程序,Web服务,MVC Web应用程序…)
编辑:让我熟悉ASP.NET WebForms领域的情况
我从来没有使用过我的细节.不幸的是,WebForms要求您在每个Page类中都有一个无参数的构造函数,因此您无法从顶部的对象图形到底部使用构造函数注入.
然而,在咨询了Mark Seeman关于在WebForms中编写对象的章节之后,我可以重新说明如何处理该框架的低效率,同时仍然符合良好的DI实践:
>有一个负责解决依赖关系的类,使用你设置的Ninject的内核.这可能是内核周围非常薄的包装.让我们称它为DependencyContainer.
>创建容器并将其保存在应用程序上下文中,以便在需要时准备就绪
protected voID Application_Start(object sender,EventArgs e){ this.Application["container"] = new DependencyContainer();}
>让我们假设你的页面类(让我们称之为HomePage)具有对ICustomerBusinessConsumer的依赖.然后DependencyContainer必须允许我们检索一个ICustomerBusinessConsumer的实例:
public ICustomerBusinessConsumer ResolveCustomerBusinessConsumer(){ return Kernel.Get<ICustomerBusinessConsumer>();}
>在MainPage类本身中,您将在默认构造函数中解析其依赖关系:
public MainPage(){ var container = (DependencyContainer) httpContext.Current.Application["container"]; this.customerBusinessConsumer = container.ResolveCustomerBusinessConsumer();}
几个注释:
>在httpContext中具有可用的依赖项容器不能太诱人地将其视为服务定位器.实际上,这里最好的做法(至少从DI到DI的角度来看)就是要有一些“实现者”类,你将继承你的页面类的功能.
例如,MainPage处理的每个 *** 作将只会转发给其实现者类.这个实现者类将是MainPage的依赖,并且与所有其他依赖关系一样,将使用容器来解析.
重要的部分是这些实现者类应该在不引用ASP.NET程序集的程序集中,因此没有机会访问httpContext编写这么多代码来实现这一点当然不是理想的,但这只是框架限制的结果.例如,在ASP.NET MVC应用程序中,以更好的方式处理这个问题.在这里,您可以单点编写对象图,并且您不必像在WebForms中一样在每个顶级类中解决它们.>好的是,当你必须在页面类构造函数中写一些管道代码时,从对象图中可以使用构造函数注入
总结以上是内存溢出为你收集整理的c# – 如何访问Ninject.Kernel而不使用Service Locator模式全部内容,希望文章能够帮你解决c# – 如何访问Ninject.Kernel而不使用Service Locator模式所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)