SORU
25 AĞUSTOS 2011, PERŞEMBE


ASP.NET içine enjekte bağımlılıkları 3 eylem filtreler MVC. Ne'ın bu yaklaşım?

İşte Kur. Bir hizmet: bir örneği gereken bazı eylem filtre var

public interface IMyService
{
   void DoSomething();
}

public class MyService : IMyService
{
   public void DoSomething(){}
}

Ben bu hizmetin bir örneği gereken bir ActionFilter var:

public class MyActionFilter : ActionFilterAttribute
{
   private IMyService _myService; // <--- How do we get this injected

   public override void OnActionExecuting(ActionExecutingContext filterContext)
   {
       _myService.DoSomething();
       base.OnActionExecuting(filterContext);
   }
}

Eyleme MVC 1/2 bağımlılıkları enjekte filtreleri baş belası oldu. En yaygın yaklaşım kullanmak özel bir eylem ınvoker olarak görülebilir, burada: http://www.jeremyskinner.co.uk/2008/11/08/dependency-injection-with-aspnet-mvc-action-filters/ ana motivasyon arkasında bu geçici çözüm, çünkü bu, aşağıdaki yaklaşım olduğunu kabul özensiz ve sıkı kavrama ile konteyner:

public class MyActionFilter : ActionFilterAttribute
{
   private IMyService _myService;

   public MyActionFilter()
      :this(MyStaticKernel.Get<IMyService>()) //using Ninject, but would apply to any container
   {

   }

   public MyActionFilter(IMyService myService)
   {
      _myService = myService;
   }

   public override void OnActionExecuting(ActionExecutingContext filterContext)
   {
       _myService.DoSomething();
       base.OnActionExecuting(filterContext);
   }
}

Burada yapıcı tableti kap kullanın ve hizmeti enjekte oluşturucu aşırı yük bindiriyoruz. Bu ActionFilter ile kap kaç yapar sıkıca katılıyorum.

Bu halde sorum şu: ASP.NET MVC Şimdi konteyner kullanılan bir soyutlama (DependencyResolver üzerinden) 3, Tüm bu çemberler hala gerekli mi? Göstermeme izin verin

public class MyActionFilter : ActionFilterAttribute
{
   private IMyService _myService;

   public MyActionFilter()
      :this(DependencyResolver.Current.GetService(typeof(IMyService)) as IMyService)
   {

   }

   public MyActionFilter(IMyService myService)
   {
      _myService = myService;
   }

   public override void OnActionExecuting(ActionExecutingContext filterContext)
   {
       _myService.DoSomething();
       base.OnActionExecuting(filterContext);
   }
}

Şimdi titiz olabilir Bazı bu alay, ama cidden, ne zararı olurdu? Test zaman bir İMyService alıyor yapıcı kullanmak ve sahte bir hizmeti bu şekilde enjekte edebileceğiniz gibi hala test edilebilir. Bu DependencyResolver kullanıyorsun beri Dİ konteyner her uygulama için aşağı bağlı değiliz, bu yüzden bu yaklaşım hiç kötü yanı yok?

Bu arada, burada MVC3 bu işi, güzel bir yaklaşım, yeni İFilterProvider arayüzü kullanarak: http://www.thecodinghumanist.com/blog/archives/2011/1/27/structuremap-action-filters-and-dependency-injection-in-asp-net-mvc-3

CEVAP
25 AĞUSTOS 2011, PERŞEMBE


Evet, lots of issues with IDependencyResolver kendisi ve Singleton Servis Belirleyicisi olarak Bastard Injection kullanımı ekleyebilirsiniz bu gibi olumsuzlukları vardır.

Daha iyi bir seçenek, istediğiniz hangisi enjekte edebilirsiniz normal bir sınıf olarak filtre uygulamak için:

public class MyActionFilter : IActionFilter
{
    private readonly IMyService myService;

    public MyActionFilter(IMyService myService)
    {
        this.myService = myService;
    }

    public void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if(this.ApplyBehavior(filterContext))
            this.myService.DoSomething();
    }

    public void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if(this.ApplyBehavior(filterContext))
            this.myService.DoSomething();
    }

    private bool ApplyBehavior(ActionExecutingContext filterContext)
    {
        // Look for a marker attribute in the filterContext or use some other rule
        // to determine whether or not to apply the behavior.
    }

    private bool ApplyBehavior(ActionExecutedContext filterContext)
    {
        // Same as above
    }
}

Süzgeç ya da davranış uygulanabilir olup olmadığını belirlemek için inceler filterContext nasıl dikkat edin.

Bu hala öznitelikleri veya filtre uygulanmış olması gerekir olup olmadığını kontrol etmek için kullanabileceğiniz anlamına gelir:

public class MyActionFilterAttribute : Attribute { }

Ancak, şimdi bu öznitelik tamamen hareketsizdir.

Filtre gerekli bağımlılığı ile oluşan ve global küresel filtreler eklenebilir.asax:

GlobalFilters.Filters.Add(new MyActionFilter(new MyService()));

MVC yerine Web API ASP.NET uygulanan bu makaleye bakın, ancak bu teknik daha ayrıntılı bir örnek için: http://blog.ploeh.dk/2014/06/13/passive-attributes

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Julian Smith

    Julian Smith

    31 EKİM 2006
  • Murray Winiata

    Murray Winia

    2 ŞUBAT 2009
  • World Science Festival

    World Scienc

    1 Mayıs 2008