AutofacがControllerのIoc(Inversion of Control)をどのように実現するかを分析する
4477 ワード
AutofacはIocフレームワークで、最大の特徴はプロファイルを使わずにC#コードで直接登録できることです.
AutofacはAspに対しても提供する.NetMVCの拡張.
ここではAutofacのドキュメントで、MVCプロジェクトで統合して使用する方法を説明します.
その過程を説明します.
1.まずContainerBuilderを作成します(後でコンテナを提供し、必要なオブジェクトインスタンスを取り出すことができます).
2.現在のAssemblyのすべてのControllersをBuilderに登録します.これにより、Builderは現在のMVCプロジェクトのすべてのControllerタイプを取得します.
3.コンテナの作成
4.MVCデフォルトのDependencyResolverをAutofacDependencyResolverに置き換える
OK. ここまで来ると、前の方が分かりやすく、最後のDependencyResolverは何をしましたか?DependencyResolverについては、まずControllerFactoryを知る必要があります.
MVCのControllerFactory
AutofacはAspに対しても提供する.NetMVCの拡張.
ここではAutofacのドキュメントで、MVCプロジェクトで統合して使用する方法を説明します.
protected void Application_Start()
{
var builder = new ContainerBuilder();
builder.RegisterControllers(typeof(MvcApplication).Assembly);
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
// Other MVC setup...
その過程を説明します.
1.まずContainerBuilderを作成します(後でコンテナを提供し、必要なオブジェクトインスタンスを取り出すことができます).
2.現在のAssemblyのすべてのControllersをBuilderに登録します.これにより、Builderは現在のMVCプロジェクトのすべてのControllerタイプを取得します.
3.コンテナの作成
4.MVCデフォルトのDependencyResolverをAutofacDependencyResolverに置き換える
OK. ここまで来ると、前の方が分かりやすく、最後のDependencyResolverは何をしましたか?DependencyResolverについては、まずControllerFactoryを知る必要があります.
MVCのControllerFactory
MVCリクエストのプロセスは、リクエストのURLに基づいて一致するRouteを見つけ、Routeが対応するControllerの名前を解析し、名前に基づいて対応するControllerタイプを見つけ、Controllerのオブジェクト応答リクエストをインスタンス化することである.
上に太字で表示されているのは、DefaultControllerFactoryがやったこと、つまりその方法CreateControllerの方法です.public virtual IController CreateController(RequestContext requestContext, string controllerName)
CreateControllerメソッドは、主にGetControllerTypeメソッドとGetControllerInstanceメソッドに依存します.protected internal virtual Type GetControllerType(RequestContext requestContext, string controllerName)
protected internal virtual IController GetControllerInstance(RequestContext requestContext, Type controllerType)
こんなに多くのvirtualの方法を見て、とても興奮していますか?これは明らかに私たちにoverrideを継承させたのではないでしょうか.もし私たちがoverrideここのGetControllerInstanceメソッドを使用して、ここのControllerTypeに基づいてIocコンテナからこのControllerTypeのインスタンスを取得すれば、万事OKではないでしょうか.
そう、GetControllerInstanceメソッドの継承と書き換えは、確かにControllerのIocを実現し、Application_Start()では、次の行のコードを使用して、DefaultControllerFactoryを置き換えます.
ControllerBuilder.Current.SetControllerFactory(new MyControllerFactory(_container));
約束したDependencyResolverは?
実際、DefaultControllerFactoryのGetControllerInstanceでは、IDependencyResolverインタフェース定義のメソッドGetService取得インスタンスが呼び出されます.このインタフェースを継承することで,従来のDependencyResolverを置き換えることで,MVCの従来の変更はより小さくなる.従って、IDependencyResolverインタフェースを継承することにより実現する方がよい.これが最初に見たことです
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
IDependencyResolver
public interface IDependencyResolver {
object GetService(Type serviceType);
IEnumerableGetServices(Type serviceType);
}
AutofacDependencyResolverのソースコードがTypeに従ってコンテナからインスタンスを取得する方法を見たい場合は、ここまでです.
思考と実践:ControllerFactoryをいつ使うか
Asp.NetMVCの中のAreaの使用、みんなは比較的に熟知したべきです.それは大きなプロジェクト、多くの人が開発した状況を解決するために使われています.area実現の原理は,ネーミング空間によって名前が同じControllerであっても区別される.しかし、いずれにしても、areaはプロジェクトの中にいます.
どのようにしてareaを異なるプロジェクトに分離することができますか?ここのGetControllerTypeの方法は良い突破口です.次にareaを異なるプロジェクトに分離する方法を検討し,より便利なプロジェクトを実現する.これもOrchard CMSモジュール実装の原理である.
public virtual IController CreateController(RequestContext requestContext, string controllerName)
protected internal virtual Type GetControllerType(RequestContext requestContext, string controllerName)
protected internal virtual IController GetControllerInstance(RequestContext requestContext, Type controllerType)
実際、DefaultControllerFactoryのGetControllerInstanceでは、IDependencyResolverインタフェース定義のメソッドGetService取得インスタンスが呼び出されます.このインタフェースを継承することで,従来のDependencyResolverを置き換えることで,MVCの従来の変更はより小さくなる.従って、IDependencyResolverインタフェースを継承することにより実現する方がよい.これが最初に見たことです
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
IDependencyResolverpublic interface IDependencyResolver { object GetService(Type serviceType); IEnumerableGetServices(Type serviceType); }
AutofacDependencyResolverのソースコードがTypeに従ってコンテナからインスタンスを取得する方法を見たい場合は、ここまでです.
思考と実践:ControllerFactoryをいつ使うか
Asp.NetMVCの中のAreaの使用、みんなは比較的に熟知したべきです.それは大きなプロジェクト、多くの人が開発した状況を解決するために使われています.area実現の原理は,ネーミング空間によって名前が同じControllerであっても区別される.しかし、いずれにしても、areaはプロジェクトの中にいます.
どのようにしてareaを異なるプロジェクトに分離することができますか?ここのGetControllerTypeの方法は良い突破口です.次にareaを異なるプロジェクトに分離する方法を検討し,より便利なプロジェクトを実現する.これもOrchard CMSモジュール実装の原理である.