web-dev-qa-db-ja.com

MVCとWebAPIコントローラーの両方のシンプルなインジェクター初期化

いくつかのリソースがDIされたWebAPIコントローラーがあります。後で必要になったので、MVCコントローラーを追加しましたが、今は同じリソースが必要です。これが私の元の構成です:

    [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);
        }
    }
}

同じ場所でMVCControllerのDIを登録することはできますか?コンテナを再利用できますか?

pdate:近くにいる必要がありますが、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);
    }
}
13
FailedUnitTest

コンテナを再利用できますか?

はい、できます。そうすべきです。通常、すべてのアプリドメインには1つのコンテナインスタンスが必要です。

Simple Injectorドキュメントの MVC統合ドキュメント は、MVC DependencyResolverを次のように設定する必要があることを説明しています。

DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));

ただし、作業を簡単にするために、WebRequestLifestyleDefaultScopedLifestyleとして登録する必要があります。

container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();

IIS内からWebAPIのみを実行しているため、これはWebAPIでも機能します。

したがって、両方のDependencyResolverを構成する必要があります。

13
Steven

また、WebRequestLifestyle()はその時点で廃止されていることに注意してください。代わりに使用できます:

//...

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

//...
1
Bruno Mósca

スティーブンの答えとその下のコメントを読んだ後、まだいくつかのエラーが発生したので、2セントを追加したいと思います。最終的に、これは物事が構成される順序と関係がありました。

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(
        ....
    }
}
1
CularBytes