简体   繁体   English

如何在ASP.NET中使用IoC容器配置单元测试?

[英]How to configure unit tests with an IoC container in ASP.NET?

I have configured Unity in my ASP.NET application and the configuration is loaded when the first request is received in Application_BeginRequest. 我已经在ASP.NET应用程序中配置了Unity,并在Application_BeginRequest中收到第一个请求时加载了配置。 then the Unity container is stored in the Global.ascx as a property so that my other class can access it: 然后将Unity容器作为属性存储在Global.ascx中,以便我的其他类可以访问它:

public static IUnityContainer ContainerHolder { get; set; }

IUnityContainer IContainerAccessor.Container
{
    get { return ContainerHolder; }
}

ContainerHolder, holds the container instance across application and Container property allows access to this property in each session. ContainerHolder,在整个应用程序中保存容器实例,并且Container属性允许在每个会话中访问此属性。

Then I have a UnityLocator class which enables me access this property across the application: 然后,我有了一个UnityLocator类,使我可以在整个应用程序中访问此属性:

public static class UnityLocator
    {        
        private static IUnityContainer Container
        {
            get
            {
                return ((IContainerAccessor)HttpContext.Current.ApplicationInstance).Container;
            }
        }
    }

Everything works fine! 一切正常!

I have also a method to access the instance from Unity: 我还有一种从Unity访问实例的方法:

UnityLocator.GetInstance<IThemeManager>();

    protected Repository(ICustomCacheManager customCacheManager)
    {
        this.Cache = customCacheManager;
    }

    protected Repository()
        : this(UnityLocator.GetInstance<ICustomCacheManager>())
    {

    }

this has been used in my app so that I can retrieve an existing instance from Unity so that I can inject it to other classes. 它已在我的应用程序中使用过,以便我可以从Unity中检索现有实例,以便将其注入到其他类中。 For example my view (asp.net page) injects this to its Presenter class as a dependency. 例如,我的视图(asp.net页)将其作为依赖项注入到Presenter类中。

Now, I'd like to configure my Unit tests to run. 现在,我想配置单元测试以运行。

How could I do that?! 我该怎么办? global.ascx doesn't exist there obviously so I thought I should create a BaseTest class and let all my tests inherit it. global.ascx显然不存在,所以我认为我应该创建一个BaseTest类并让所有测试继承它。 then at the constructor of this BaseTest class, I build up my instances. 然后在这个BaseTest类的构造函数中,建立我的实例。 Is it the right way to do it? 这是正确的方法吗?

How to configure unit tests with Unity now? 现在如何使用Unity配置单元测试?

Thanks 谢谢

UPDATE: UnityLocator.GetInstance added. 更新:UnityLocator.GetInstance已添加。

You shouldn't worry about accessing your IoC container. 您不必担心访问IoC容器。 That is a violation of Unit Tests. 这违反了单元测试。

Unit tests you should not worry about any concrete implementation or dependency (other than the class under test). 单元测试您不必担心任何具体的实现或依赖关系(被测类除外)。

To me, having your IoC globally available is a bad design choice. 对我来说,在全球范围内提供IoC是一个糟糕的设计选择。 You should have your dependencies injected via properties or constructors. 您应该通过属性或构造函数注入依赖项。

Probably using the global application class for storing the service locator was not a good idea. 可能使用全局应用程序类来存储服务定位器不是一个好主意。 Why don't you use the built-in ServiceLocator class? 为什么不使用内置的ServiceLocator类? It is available from anywhere in the code and doesn't depend on global application / HttpContext. 它可以在代码中的任何位置使用,并且不依赖于全局应用程序/ HttpContext。

Whether or not using the container in unit tests is another story. 是否在单元测试中使用容器是另一回事。 Personally I am not against it as long as you put stub implementations of your services into the container. 就个人而言,只要您将服务的存根实现放入容器中,我就不会反对。

Edit: the way to configure your container using ServiceLocator: 编辑:使用ServiceLocator配置容器的方式:

    private void ConfigureUnity()
    {
        UnityServiceLocator locator = new UnityServiceLocator( ConfigureUnityContainer() );
        ServiceLocator.SetLocatorProvider( () => locator );
    }

    private IUnityContainer ConfigureUnityContainer()
    {
        IUnityContainer container = new UnityContainer();

        // this loads container's configuration, comment or uncomment
        container.LoadConfiguration();

        return container;
    }

You can then access the container from within the locator like: 然后,您可以从定位器中访问容器,例如:

var container = ServiceLocator.Current.GetInstance<IUnityContainer>();

In your page, try doing things like this: 在您的页面中,尝试执行以下操作:

public class DepartmentReportPage : Page
{
    private readonly DepartmentReportPresenter _presenter;

    public DepartmentReportPage()
    {
        this._presenter =
            UnityLocator.GetInstance<DepartmentReportPresenter>();

        this._presenter.View = this;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用asp.net mvc和单元测试来组织代码和测试 - How to organize code and tests with asp.net mvc and unit testing ASP.NET Core 3.x - 访问 IoC 容器 - ASP.NET Core 3.x - Access IoC Container 在ASP.net解决方案中使用Unity IOC容器 - Using Unity IOC Container in ASP.net solution 标准化存储库,UnitOfWork,IOC容器Asp.Net MVC - Standardize Repository, UnitOfWork, IOC Container Asp.Net MVC ASP.NET Core与现有的IoC容器和环境? - ASP.NET Core with existing IoC container & environment? 具有IoC容器并发症的C#ASP.NET依赖注入 - C# ASP.NET Dependency Injection with IoC Container Complications 如何在单独的项目中使用测试设置ASP.NET API以使用一个IoC / DI容器 - How to set ASP.NET API with test in separate project to use one IoC/DI container 如何从ASP.NET MVC 5应用程序中的“区域”在IoC容器中注册类型? - How to register type in the IoC container from an “Area” in ASP.NET MVC 5 app? 使用Asp.Net MVC 5框架和IoC容器时,如何构造视图模型的实例? - How to construct an instance of a view-model when using Asp.Net MVC 5 framework and IoC container? 如何将已经实例化的IOC容器传递给Asp.net 5应用程序? - How can I pass an already instantiated IOC container to an Asp.net 5 application?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM