【问题标题】:Simple Injector initialize for both MVC and Web API controllersMVC 和 Web API 控制器的简单注入器初始化
【发布时间】:2016-05-31 14:30:16
【问题描述】:

我有一个 Web API 控制器,其中包含一些 DI 资源。出于以后的需要,我添加了一个 MVC 控制器,现在我也需要相同的资源 DI。这是我原来的配置:

    [assembly: WebActivator.PostApplicationStartMethod(typeof(CineplexSearch.App_Start.SimpleInjectorWebApiInitializer), "Initialize")]

namespace CineplexSearch.App_Start
{
    using System.Web.Http;
    using SimpleInjector;
    using SimpleInjector.Integration.WebApi;

    public static class SimpleInjectorWebApiInitializer
    {
        /// <summary>Initialize the container and register it as Web API Dependency Resolver.</summary>
        public static void Initialize()
        {
            var container = new Container();
            container.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle();

            InitializeContainer(container);

            container.RegisterWebApiControllers(GlobalConfiguration.Configuration);

            container.Verify();

            GlobalConfiguration.Configuration.DependencyResolver =
                new SimpleInjectorWebApiDependencyResolver(container);
        }

        private static void InitializeContainer(Container container)
        {
            container.Register<ICachingManager, CachingManager>(Lifestyle.Transient);
            container.Register<IDataAccessLayer, DataAccessLayer>(Lifestyle.Transient);
        }
    }
}

我也可以在同一个地方为 MVC 控制器注册 DI 吗?我可以重复使用容器吗?

更新:我必须关闭,但现在我在 Web API 控制器中收到错误,我需要一个无参数构造函数;我尝试添加它,但当然没有注入任何东西

public static class SimpleInjectorWebApiInitializer
{
    /// <summary>Initialize the container and register it as Web API Dependency Resolver.</summary>
    public static void Initialize()
    {
        var container = new Container();
        container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();

        InitializeContainer(container);

        container.RegisterWebApiControllers(GlobalConfiguration.Configuration);
        container.RegisterMvcControllers(Assembly.GetExecutingAssembly());

        container.Verify();

        //GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);
        DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
    }

    private static void InitializeContainer(Container container)
    {
        container.Register<ICachingManager, CachingManager>(Lifestyle.Transient);
        container.Register<IDataAccessLayer, DataAccessLayer>(Lifestyle.Transient);
    }
}

【问题讨论】:

    标签: c# asp.net-mvc dependency-injection simple-injector


    【解决方案1】:

    我可以重复使用容器吗?

    是的,你可以,你应该这样做。每个应用程序域通常应该有一个容器实例。

    Simple Injector 文档的MVC integration documentation 解释说,您应该如下设置MVC DependencyResolver

    DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
    

    不过,为了方便起见,您应该将WebRequestLifestyle 注册为DefaultScopedLifestyle

    container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();
    

    这也适用于 Web API,因为您只在 IIS 中运行 Web API。

    所以你需要同时配置 DependencyResolver。

    【讨论】:

    • 感谢您的快速回复,我几乎可以正常工作了,您能看看我的更新吗?
    • @FailedUnitTest 你需要 both 依赖解析器。所以 Web API 依赖解析器也是如此。
    • 我完全理解,我们应该同时使用.RegisterMvcControllers()RegisterWebApiControlers() 以及both System.Web.Mvc.DependencyResolver(new SimpleInjectorDependencyResolver(container)) and GlobalConfiguration.Configuration.DependencyResolver(new SimpleInjectorWebApiDependencyResolver(container)) ?
    • @Dr.Zim:如果你同时使用 Web API 和 MVC:是的。
    • 谢谢@Dr.Zim。通过您的评论,我理解了整个答案。
    【解决方案2】:

    我想加两分钱,因为在阅读了史蒂文的答案和它下面的 cmets 之后,我仍然遇到了一些错误。最终这与配置的顺序有关。

    protected void Application_Start()
    {
        //set the default scoped lifestyle
        Container container = new Container();
        container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();
    
        ...
        //do class registration here. I did it with Scoped lifestyle
        ...
        //Let the SimpleInjector.Intergration packages register the controllers.       
        container.RegisterWebApiControllers(GlobalConfiguration.Configuration);
        container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
    
        AreaRegistration.RegisterAllAreas();
        //This must be here because we first need to do above before registering the web api. See WebApiConfig code.
        GlobalConfiguration.Configure(WebApiConfig.Register);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
    
        //don't set the resolver here, do it in WebApiConfig.Register()
        //DependencyResolver.SetResolver(new SimpleInjectorWebApiDependencyResolver(container));
        DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
        container.Verify(SimpleInjector.VerificationOption.VerifyAndDiagnose);
    }
    

    WebApiConfig:

    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API routes
            config.MapHttpAttributeRoutes();
            //set the webApi resolver here!
            config.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(DependencyInjectionCoreSetup._Container);
            //then the rest..
            var route = config.Routes.MapHttpRoute(
            ....
        }
    }
    

    【讨论】:

    • DependencyInjectionCoreSetup?
    【解决方案3】:

    还要注意 WebRequestLifestyle() 在当时已经过时。 您可以改用:

    //...
    
    container.Options.DefaultScopedLifestyle = new SimpleInjector.Lifestyles.AsyncScopedLifestyle();
    
    //...
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-17
    • 1970-01-01
    • 2014-06-01
    • 1970-01-01
    • 2016-02-22
    相关资源
    最近更新 更多