c# – 如何访问Ninject.Kernel而不使用Service Locator模式

c# – 如何访问Ninject.Kernel而不使用Service Locator模式,第1张

概述我已经阅读了关于这个主题的几十个帖子,没有找到一个明确的准则,如何访问Ninject.Kernel而不使用服务定位器模式. 我目前在需要使用CustomerBusiness(这是我的服务)的课程中有以下这些,它的工作正常,但我很清楚,这不是推荐的方法. private CustomerBusiness _customerBusiness;private ICustomerRepository 我已经阅读了关于这个主题的几十个帖子,没有找到一个明确的准则,如何访问Ninject.Kernel而不使用服务定位器模式.

我目前在需要使用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模式所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1239140.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存