13

ASP.NET MVC コントローラーに依存性注入を実装する場合は、IControllerFactoryインターフェイスを使用してファクトリ クラスを作成し、次のように Global.asax.cs に登録できます。

ControllerBuilder.Current.SetControllerFactory(controllerFactory)

(参考:http ://www.dotnetcurry.com/ShowArticle.aspx?ID=786 )

今私の質問は:

IHttpControllerActivator派生クラスのファクトリを設定するにはどうすればよいですか?

ASP.NET MVC 4.0 には次のようなものがありますか。

HttpControllerBuilder.Current.SetApiControllerActivator(httpControllerActivator)

?


アップデート:

現在のコードを追加したいのですが、ケースを理解すると役立つ場合があります。

私のカスタマイズされた HttpControllerActivator:

public class MyCustomApiActivator : DefaultHttpControllerActivator 
                                    //or IHttpControllerActivator ?
{
    private readonly Dictionary<string, Func<HttpRequestMessage, IHttpController>> _apiMap;

    public MyCustomApiActivator(IMyRepository repository)
    {
        if (repository == null)
        {
            throw new ArgumentException("repository");
        }
        _apiMap = new Dictionary<string, Func<HttpRequestMessage, IHttpController>>();
        controllerMap["Home"] = context => new HomeController();
        _apiMap["MyCustomApi"] = context => new MyCustomApiController(repository);
    }

    public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
    {
        if(_apiMap.ContainsKey(controllerType.Name))
            return _apiMap[controllerType.Name](request);
        return null;
    }
}

私の構成ルート:

public class CompositionRoot
{
    private readonly IHttpControllerActivator _apiControllerActivator;

    public CompositionRoot()
    {
        _apiControllerActivator = CompositionRoot.CreateHttpControllerActivator();
    }

    public IHttpControllerActivator ApiControllerActivator
    {
        get { return _apiControllerActivator; }
    }

    private static IHttpControllerActivator CreateHttpControllerActivator()
    {
        string defaultRepositoryTypeName = ConfigurationManager.AppSettings["DefaultRepositoryTypeName"];
        var defaultRepositoryType = Type.GetType(defaultRepositoryTypeName, true);
        var defaultRepository = (IMyRepository)Activator.CreateInstance(defaultRepositoryType);

        var apiController = new MyCustomApiActivator(defaultRepository);
        return apiController;
    }
}

最後に、これは私Global.asax.csの中にあり、トリックが必要です:

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);


        var root = new CompositionRoot();
        //The following line raise this compile-time error:
        // cannot convert from 'System.Web.Http.Dispatcher.IHttpControllerActivator' 
        //                to 'System.Web.Mvc.IControllerFactory'
        ControllerBuilder.Current.SetControllerFactory(root.ApiControllerActivator);
    }
4

2 に答える 2

9

.NET での Dependency Injection の著者である Mark Seemann は、ASP.NET WebAPI を使用した DI に関する短い連載を行っています。

彼は構成ルートをIHttpControllerActivator

  1. ASP.NET Web API による依存関係の挿入と有効期間の管理
  2. Castle Windsor を使用した ASP.NET Web API での依存関係の挿入

たぶんそれが役立ちます。


アップデート

GlobalConfiguration.Configuration.Services.Replace(
  typeof(IHttpControllerActivator),
  new PoorMansCompositionRoot());

カスタムをHttpControllerActivatorグローバルに登録します。

于 2012-10-22T20:52:46.947 に答える
1

ASP.NET では、Web APIHttpControllerDispatcherがコントローラーの構築を担当します。デフォルトでは DependecyResolver で動作しますが、その機能を拡張したい場合は、SendAsync メソッドをオーバーライドして再度登録する必要があります。

例:

public class MyCustomDispatcher : HttpControllerDispatcher {

    protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, 
        CancellationToken cancellationToken) {

        // Do your stuff here

        // According to your requirements, either run its default functionality 
        // or return your own stuff
        return base.SendAsync(request, cancellationToken);
    }
}

ノート:

ただし、デフォルトのものをグローバルに置き換えるエレガントな方法を見つけることができませんでした。このカスタム ディスパッチャをルートにアタッチすることで、ルートごとにデフォルトのものを簡単に置き換えることができますが、これをグローバルに行う方法はないようです。私はプロジェクト サイトでそれに関する議論を開始しました: http://aspnetwebstack.codeplex.com/discussions/400366

于 2012-10-22T19:53:05.147 に答える