هل من الممكن استخدام حقن التبعية/IOC على ASP.NET MVC filterattribute؟
سؤال
لديّ مخصص بسيط FilterAttribute
الذي أستخدمه تزيين مختلف ActionMethods
.
على سبيل المثال.
[AcceptVerbs(HttpVerbs.Get)]
[MyCustomFilter]
public ActionResult Bar(...)
{ ... }
الآن ، أود أن أضيف بعض التسجيل إلى هذا العمل المخصص .. لذا كوني فتى جيد ، أنا أستخدم DI/IoC
... وعلى هذا النحو من الرغبة في استخدام هذا النمط لعرفتي FilterAttribute
.
لذلك إذا كان لدي ما يلي ...
ILoggingService
وترغب في إضافة هذا العرف الخاص بي FilterAttribute
.. لست متأكدا كيف. مثل ، من السهل بالنسبة لي أن أفعل ما يلي ...
public class MyCustomFilterAttribute : FilterAttribute
{
public MyCustomFilterAttribute(ILoggingService loggingService)
{ ... }
}
لكن أخطاء المترجم تقول السمة التي تزين بلدي ActionMethod
(المذكورة أعلاه...) يتطلب 1 arg .. لذلك لست متأكدًا مما يجب فعله :(
المحلول
لقد حصلت على حقن الممتلكات مع العمل مع تسعة و ال ninject.web.mvc.
طالما أن لديك مصنع وحدة التحكم من ninject.web.mvc ، الأمر بسيط إلى حد ما.
على سبيل المثال
public class EventExistsAttribute : FilterAttribute, IActionFilter
{
[Inject]
public IEventRepository EventRepo { private get; set; }
public void OnActionExecuting(ActionExecutingContext filterContext)
{
//Do stuff
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
//Do something else if you so wish...
}
}
إنه يتمتع بعلامة تبعية "خفية" بشكل أساسي ، حتى أقول ... ولكن لا يوجد الكثير مما يمكنك فعله حيال ذلك.
HTHS ،
تشارلز
نصائح أخرى
تحتاج إلى كتابة iActionInvoker الخاصة بك والقيام بحقن الممتلكات. القي نظرة على هذه بعد جيمي بوجارد للأفكار.
نعم ، من الممكن استخدام حقن التبعية على مرشح. ومع ذلك ، لا يمكن استخدام حقن المنشئ على مرشح. هذا ليس قيودًا على ASP.NET MVC ، إنه أمر شائع للجميع .NET Code ، مثل تقتصر القيم التي تم تمريرها في قضاء السمات على أنواع بسيطة.
[MyFilter(ILogger logger)] // this will not compile
public ActionResult Index()
{
return View();
}
وبالتالي فإن الممارسة الشائعة هي جعل التبعية أ منشأه من المرشح الخاص بك ، كما في مثال @تشارلينو. يمكنك بعد ذلك استخدام حقن الممتلكات. يمكنك استخدام Ninject لتزيين خاصية المرشح كما في مثال @Charlino. أو كما اقترح Mrydengren ، يمكنك القيام بذلك في فئة فرعية مخصصة من ControllerActionInvoker.