मैंने कक्षा पुस्तकालय के साथ एक दिलचस्प डिजाइन समस्या में भाग लिया है जिसे मैं लिख रहा हूं। मैं AuthorizeAttribute के एक कस्टम कार्यान्वयन कि मैं ग्राहकों को इस तरह का उपयोग करने में सक्षम होना चाहते हैं:कक्षा पुस्तकालय में AuthorizeAttribute में निर्भरता इंजेक्शन
[Protected("permission_name")]
उपरोक्त कोड में, PermissionAttribute AuthorizeAttribute से विरासत और एक स्थानीय डिफ़ॉल्ट का उपयोग करता है (DefaultContext HttpContext उपयोग कर बनाई गई)।
दृश्यों के पीछे, विशेषता उपयोगकर्ताओं के लिए भूमिकाओं और अनुमतियों की जांच करने के लिए सुरक्षा सेवा का उपयोग करती है (सुरक्षा सेवा स्वयं क्लाइंट द्वारा प्रदत्त दृढ़ता सेवा का उपयोग करती है जो वे अपने ऐप की संरचना रूट में वायर कर सकते हैं)।
इसलिए मेरे गुणों को सुरक्षा सेवा के संदर्भ में कार्य करने की आवश्यकता है। चूंकि विशेषता रचनाकारों में केवल संकलन-समय स्थिरांक हो सकते हैं, मैं कन्स्ट्रक्टर इंजेक्शन का उपयोग नहीं कर सकता।
मैं एक डि ढांचे का उपयोग करने के लिए अपने ग्राहकों के लिए मजबूर नहीं करना चाहते - वे , एक आईओसी लाइब्रेरी का उपयोग कर यदि चाहें तो बिना और तार उनकी संरचना जड़ में आवश्यक निर्भरता की खोज करने के लिए सक्षम होना चाहिए।
- पुस्तकालय एक सिंगलटन SecurityService का उपयोग है:
यहाँ मेरी विकल्प हैं।
- उपयोग संपत्ति इंजेक्शन, जो काम करेगा लेकिन
- यह निर्भरता होगा वैकल्पिक लगते हैं, जो यह नहीं है और
- मैं नहीं जानता कि मैं कहाँ एक अधिकृत विशेषता पर एक MVC अनुप्रयोग में संपत्ति इंजेक्शन कर सकते हैं ।
ऊपर 2. करने के लिए सम्भावित समाधान की तरह आवेदन स्टार्टअप पर विशेषता पर एक स्थिर संपत्ति के रूप में SecurityService का एक उदाहरण स्थापित करने और इसे एक बार से अधिक सेट होने से रोकने के लिए एक गार्ड खंड का उपयोग करते हैं करने के लिए, है यह:
class ProtectedAttribute : ...
{
private static ISecurityService _SecurityService ;
public static ISecurityService SecurityService
{
get
{
return _SecurityService ;
}
set
{
if (_SecurityService != null)
throw new InvalidOperationException("You can only set the SecurityService once per lifetime of this app.") ;
_SecurityService = value ;
}
}
}
सुरक्षा सेवा एक अमूर्त सेवा मुखौटा हो सकती है ताकि इसे एक अलग कार्यान्वयन द्वारा विस्तारित/प्रतिस्थापित किया जा सके।
क्या इस समस्या को हल करने का कोई बेहतर तरीका है?
अद्यतन: कुछ कोड जोड़ने को दिखाने के लिए कि कैसे मैं यह करने के लिए जा रहा हूँ:
public class ProtectedAttribute : ...
{
private string _Permission ;
public string Permission { get { return _Permission ; } /*...*/ }
public ProtectedAttribute(string permission) { /*...*/ }
}
सेटअप एक प्राधिकरण फिल्टर और निर्भरता कॉन्फ़िगर करें:
विशेषता है कि अनुमति देता है नाम पर एक सार्वजनिक संपत्ति जोड़ें Ninject के माध्यम से (Ninject का उपयोग करके):
using Ninject.Web.Mvc.FilterBindingSyntax;
public class MyModule : Ninject.Modules.NinjectModule
{
public override void Load()
{
// mySecurityService instance below can have a singleton lifetime - perfect!
this.BindFilter<MyAuthorizationFilter>(FilterScope.Action, 0)
.WhenActionMethodHas<ProtectedAttribute>()
.WithConstructorArgument("securityService", mySecurityService)
.WithConstructorArgumentFromActionAttribute<ProtectedAttribute>("permission", p => p.PermissionName) ;
}
}
ओह यह है ... सुंदर sniffle
के अनुकूल नहीं होना चाहिए यह एएसपी.नेट एमवीसी 3 है? –
@ डारिन: हां न्यूनतम एमवीसी 3 की आवश्यकता है स्वीकार्य है। टैग अपडेट किया गया। –
संबंधित: http://stackoverflow.com/questions/7192543/injecting-dependencies-into-asp-net-mvc-3-action-filters-whats-wrong-with-this/7194467#7194467 'IFilterProvider के लिए –