Microsoft Unity を使用して、ASP.NET MVC 3 アプリケーションで依存性注入を機能させようとしています。最初に、独自の IDependencyResolver を実装し、次のように Global.asax ファイルでアクティブにしました。
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
コントローラー インジェクション (コンストラクターと [Dependency] 属性の両方を介して) を機能させるために、他に何もする必要がないことがわかりました。デフォルトのビューエンジンを使用すると、[Dependency] 属性を標準ビューで機能させることができますが、レイアウトビューでは機能しません。これをレイアウトビューでも機能させることは可能ですか?
ただし、CreateView/CreatePartialView メソッドをオーバーライドし、独自のカスタム ビューを返す (IView を実装する) VirtualPathProviderViewEngine から継承する独自のビュー エンジンを実装しました。以下のカスタム ビューの Render メソッドを参照してください。
public void Render(ViewContext viewContext, TextWriter writer) {
var webViewPage = DependencyResolver.Current.GetService(_type) as WebViewPage;
//var webViewPage = Activator.CreateInstance(_type) as WebViewPage;
if (webViewPage == null)
throw new InvalidOperationException("Invalid view type");
webViewPage.VirtualPath = _virtualPath;
webViewPage.ViewContext = viewContext;
webViewPage.ViewData = viewContext.ViewData;
webViewPage.InitHelpers();
WebPageRenderingBase startPage = null;
if (_runViewStartPages)
startPage = StartPage.GetStartPage(webViewPage, "_ViewStart", _viewStartFileExtensions);
var pageContext = new WebPageContext(viewContext.HttpContext, webViewPage, null);
webViewPage.ExecutePageHierarchy(pageContext, writer, startPage);
}
コメントアウトされた行で、ビュー内の依存性注入が完全に失われたため、上記の行に変更しました。これは、標準ビューでは正常に機能しますが、レイアウト ビューでは機能しません。上記をレイアウトビューでも機能するように変更する方法を教えていただければ幸いです。
最後に、アクションフィルターインジェクションも機能させようとしています。私は2つの異なるケースを見つけました:
属性を介してフィルターをアクションに適用します。
グローバル フィルターとして定義します。たとえば、次のようになります。
GlobalFilters.Filters.Add(新しい TestAttribute());
どちらも依存関係リゾルバーを使用していないようです。したがって、追加の作業を行う必要があります。より良い方法があれば修正してください。最初のシナリオを有効にするために、次のことを行いました。
public class UnityFilterAttributeFilterProvider : FilterAttributeFilterProvider {
private IUnityContainer _container;
protected override IEnumerable<FilterAttribute> GetControllerAttributes(ControllerContext controllerContext, ActionDescriptor actionDescriptor) {
var attributes = base.GetControllerAttributes(controllerContext, actionDescriptor);
foreach (var attribute in attributes) {
_container.BuildUp(attribute.GetType(), attribute);
}
return attributes;
}
protected override IEnumerable<FilterAttribute> GetActionAttributes(ControllerContext controllerContext, ActionDescriptor actionDescriptor) {
var attributes = base.GetActionAttributes(controllerContext, actionDescriptor);
foreach (var attribute in attributes) {
_container.BuildUp(attribute.GetType(), attribute);
}
return attributes;
}
}
そして、これを Global.asax ファイル内で次のように定義しました。
FilterProviders.Providers.Remove(FilterProviders.Providers.Single(f => f is FilterAttributeFilterProvider));
FilterProviders.Providers.Add(new UnityFilterAttributeFilterProvider(container));
これは問題なく動作しますが、これが正しい方法であるかどうか疑問に思っていましたか? 2 番目のケースを解決するために、グローバル フィルターを定義した場所を次のように変更しました。
GlobalFilters.Filters.Add(DependencyResolver.Current.GetService<TestAttribute>());
これも機能するようになりましたが、これは正しい方法ですか?
助けていただければ幸いです。ありがとう