2012-10-22 16 views
11

, ben gibi, bir fabrika sınıfı oluşturmak ve sonra Global.asax.cs içinde kaydettikten IControllerFactory arabirimini kullanabilirsiniz: http://www.dotnetcurry.com/ShowArticle.aspx?ID=786)ASP.NET Web API için HttpControllerBuilder var mı?</p> <pre><code>ControllerBuilder.Current.SetControllerFactory(controllerFactory) </code></pre> <p>(referans: ASP.NET MVC denetleyicileri için bir Bağımlılık enjeksiyon uygulamak istiyorsanız

Şimdi sorum şu:

Nasıl bir IHttpControllerActivator türetilmiş bir sınıf için bir fabrika set olabilir?

HttpControllerBuilder.Current.SetApiControllerActivator(httpControllerActivator) 

:

biz gibi ASP.NET MVC 4.0 bir şey var mı?


Güncelleme: benim şimdiki kodu eklemek istediğiniz

, durumda anlamak için yararlı olabilir:

Benim özelleştirilmiş 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; 
    } 
} 

My kompozisyon kök:

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

Nihayet bu bir hile gerek benim Global.asax.cs, içeride:

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

cevap

8

Mark Seemann, .NET Dependency Injection yazarı ASP.NET WebAPI ile DI üzerinde kısa dizi vardır.

O yardımcı olur Belki bir IHttpControllerActivator

  1. Dependency Injection and Lifetime Management with ASP.NET Web API
  2. Dependency Injection in ASP.NET Web API with Castle Windsor

içindeki kompozisyon kök yerleştirir.


Güncelleme

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

Saklayıcılar küresel özel HttpControllerActivator.

+0

"Create" yöntemi hangi nedenle ateş etmiyor? Ben genel bir denetleyicisi dönmek 'kamu IHttpController oluştur ( HttpRequestMessage isteği HttpControllerDescriptor controllerDescriptor, Tip _controllerType) {return (IHttpController) yeni GenericApiController (); } ' – Bellash

1

ASP.NET Web API olarak HttpControllerDispatcher denetleyicileri inşa sorumludur. DependecyResolver ile varsayılan olarak çalışır ancak işlevselliğini genişletmek isterseniz, SendAsync yöntemini geçersiz kılmanız ve yeniden kaydetmeniz gerekir.

Örnek:

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

Not:

Ancak, ben bir küresel varsayılan yerine zarif bir yol bulmak mümkün değildi. Bu özel dağıtıcıyı bir rotaya iliştirerek tarafından rota başına varsayılan bir tane kolayca değiştirebilirsiniz, ancak genel olarak bunu yapmak için yolu yok gibi görünüyor. Ben proje sahasında bu konuda bir tartışma açtı: http://aspnetwebstack.codeplex.com/discussions/400366

İlgili konular