私は、Web アプリに IoC を実装するための詳細を調べてきましたが、Microsoft.Practices.ServiceLocation を活用する方法で行いました。私は特に Autofac と asp.net の統合を使用していますが、他のコンテナーに対して自分自身を開いたままにしたかったのです。この質問の行に沿って、Web アプリ コードでコンテナーにアクセスする方法が心配でした。
主に解決するインターフェイスを定義する「コア」ライブラリがあります。このコア ライブラリは、私の Web アプリや他のアプリでも使用されています。共通のインターフェースを定義すると非常に便利です。これは、IoC コンテナーへのアクセスを配置するのに最適な場所だと思い、静的クラスを使用して実行しました。トリックは、コンテナを静的クラスに注入することです。
Web 環境ではコンテナがリクエストごとに異なる可能性があるため注意が必要ですが、Web 以外のアプリでは常に同じになる可能性があります。最初はコンテナにメソッドを直接注入しようとしましたが、次の Web リクエストですぐに失敗しました。だから私はこれを思いついた:
public static class IoCContainer
{
public static void SetServiceLocator(Func<IServiceLocator> getLocator)
{
m_GetLocator = getLocator;
}
static private Func<IServiceLocator> m_GetLocator = null;
public static T GetInstance<T>(string typeName)
{
return m_GetLocator().GetInstance<T>(typeName);
}
}
今私のglobal.asax.csでこれを行います:
protected void Application_Start(object sender, EventArgs e)
{
var builder = new Autofac.Builder.ContainerBuilder();
... register stuff ...
var container = builder.Build();
_containerProvider = new Autofac.Integration.Web.ContainerProvider(container);
Xyz.Core.IoCContainer.SetServiceLocator(() =>
new AutofacContrib.CommonServiceLocator.AutofacServiceLocator
(_containerProvider.RequestContainer));
}
public IContainerProvider ContainerProvider
{
get { return _containerProvider; }
}
static IContainerProvider _containerProvider;
そして、依存関係を解決するための呼び出しは次のようになります
var someService = Xyz.Core.GetInstance<ISomeService>();
したがって、特定のコンテナーを渡すのではなく、コンテナーを取得する方法を知っているデリゲートを渡します。非 Web アプリケーションの場合、デリゲートはおそらく build() が提供するものを返すだけです。
専門家への私の質問は、これは理にかなっていますか? コンテナー製品が何であるか、またはコンテナー自体がどこから来たのかを知らなくても、依存関係を解決できるものにたどり着く簡単な方法があります。どう思いますか?