在 ASP.NET MVC 3 应用程序的类库中引用 Ninject

发布于 2024-12-12 11:30:11 字数 1218 浏览 0 评论 0原文

我有一个 ASP.NET MVC 3 应用程序,它使用 Ninject.MVC3 扩展在我的 MVC 应用程序中设置 DI。也就是说,在定义我的绑定的 App_Start 文件夹中有一个 NinjectMVC3.cs 文件。这对于 DI 到我的应用程序的控制器来说效果很好。

除了 ASP.NET MVC Web 应用程序之外,我的解决方案还包含一个类库项目,我们将其称为 MyProject.Core,其中包含我的域模型、服务等。在那里,我有一个名为 UserServices 的类,它使用名为 EmailServices 的服务,如下所示:

public class UserServices : IUserServices
{        
    private readonly IEmailServices _emailServices = new EmailServices();

    public void CreateUser(...)
    {
        // Create user...

        _emailServices.SendWelcomeEmail(newUser);
    }
}

如您所见,UserServices 类有一个硬对 EmailServices 的编码依赖项,但我也希望将其配置为使用 DI。也就是说,在我的 ASP.NET MVC 应用程序(或单元测试项目或任何地方)中,我希望能够说“绑定 IEmailServices 以使用 TestEmailServices”并具有 < code>UserServices 类使用 TestEmailServices 而不是 EmailServices

我该怎么做呢?我希望能够做类似的事情:

public class UserServices : IUserServices
{        
    private readonly IEmailServices _emailServices = kernel.Get<EmailServices>();

    ...
}

但在这种情况下,我不确定 kernel 从哪里来。我问的有道理吗,还是我在这里吠叫错了树?

谢谢

I have an ASP.NET MVC 3 application that uses the Ninject.MVC3 extension to setup DI in my MVC application. Namely, there's the NinjectMVC3.cs file in the App_Start folder where my bindings are defined. This works well for DI into my application's controllers.

In addition to the ASP.NET MVC web application, my Solution also contains a class library projects, let's call it MyProject.Core, which has my domain model, services, and so on. In there I have a class called UserServices that uses a service called EmailServices, like so:

public class UserServices : IUserServices
{        
    private readonly IEmailServices _emailServices = new EmailServices();

    public void CreateUser(...)
    {
        // Create user...

        _emailServices.SendWelcomeEmail(newUser);
    }
}

As you can see, the UserServices class has a hard-coded dependency on EmailServices, but I'd like for that to be configured to use DI, as well. Namely, in my ASP.NET MVC application (or unit test project or wherever) I want to be able to say, "Bind IEmailServices to use TestEmailServices" and have the UserServices class use TestEmailServices instead of EmailServices.

How do I go about doing this? I'd like to be able to do something like:

public class UserServices : IUserServices
{        
    private readonly IEmailServices _emailServices = kernel.Get<EmailServices>();

    ...
}

But I'm not sure where kernel is going to come from, in this case. Is what I'm asking making any sense, or am I barking up the wrong tree here?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

甜味超标? 2024-12-19 11:30:11

您应该能够通过构造函数注入来完成此操作,如下所示:

private readonly IEmailServices _emailServices;

public UserServices(IEmailServices emailServices)
{
    _emailServices = emailServices;
}

控制器中的服务注入应由 Ninject 自定义控制器工厂自动处理,该工厂将使用配置的 IoC 容器来解析 IUserServices创建控制器时创建一个 IEmailServices 对象,然后容器将为其提供一个 IEmailServices 对象:

public class MyController : Controller
{
    private readonly IUserServices _userServices;

    public MyController(IUserServices userServices)
    {
        _userServices = userServices;
    }
}

在进行单元测试时,您可以手动将虚假或模拟电子邮件服务注入到用户服务中。

You should be able to do this with constructor injection, like this:

private readonly IEmailServices _emailServices;

public UserServices(IEmailServices emailServices)
{
    _emailServices = emailServices;
}

The service injection into your controllers should be handled automatically by the Ninject custom controller factory, which'll use the configured IoC container to resolve the IUserServices object when the controller is created, which will in turn be given an IEmailServices object by the container:

public class MyController : Controller
{
    private readonly IUserServices _userServices;

    public MyController(IUserServices userServices)
    {
        _userServices = userServices;
    }
}

When you're unit testing, you can manually inject a fake or mock email service into the user service.

何以笙箫默 2024-12-19 11:30:11

如果您无论如何都在使用 MVC 3,那么使用内置的 DependencyResolver 注册 Ninject 怎么样?

System.Web.Mvc.DependencyResolver.SetResolver(yourKernel);

然后,您就可以在

var svc = System.Web.Mvc.DependencyResolver.Current.GetService<bla>();

需要的地方使用它。我不知道 SetResolver 是否直接接受 Ninject Kernel 或者您是否需要包装类,但我认为这是最干净的解决方案。

If you are using MVC 3 anyway, how about registering Ninject with the built-in DependencyResolver?

System.Web.Mvc.DependencyResolver.SetResolver(yourKernel);

Then, you can just use

var svc = System.Web.Mvc.DependencyResolver.Current.GetService<bla>();

where you need it. I don't know off hand if SetResolver accepts the Ninject Kernel directly or if you need a wrapper class, but I'd consider that the cleanest solution.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文