2012-12-19 11 views
9

मैं एक मोबाइल एप्लिकेशन में एक JSON इंटरफेस के लिए सी # में एएसपी.NET वेब एपीआई प्रोजेक्ट पर काम कर रहा हूं। मेरा विचार सभी अनुरोधों के लिए इंटरफेस बनाना था और फिर वेब एपीआई कोड में इन इंटरफेस का उपयोग करना था।एएसपी.नेट वेब एपीआई एक्शन विधि पैरामीटर के लिए निर्भरता इंजेक्शन

public interface IApiObject {} 
public interface IApiResponse<T> : IApiObject where T : IApiObject {} 
public interface IApiRegistrationRequest : IApiObject {} 

मेरे नियंत्रक इस तरह दिखता है:

public class MyApiController : ApiController 
{ 

    public IApiResponse<IApiObject> Register(IApiRegistrationRequest request) { 
     // do some stuff 
    } 
} 

मेरे जाल एपीआई परियोजना भी इन इंटरफेस के कार्यान्वयन में शामिल है

मैं कुछ इस तरह के साथ समाप्त हो गया।

मैं वेब एपीआई परियोजनाओं MVC परियोजनाओं जैसे बाध्यकारी है मॉडल का उपयोग मान लिया, इसलिए मैं सभी IApiObjects और कस्टम मॉडल बांधने की मशीन उनके कार्यान्वयन के लिए इंटरफेस को हल करने के लिए एक एकता कंटेनर का उपयोग कर के लिए एक बांधने की मशीन प्रदान करने के लिए एक inheritance aware ModelBinderProvider बनाया।

हालांकि, कुछ और जांच के बाद, मैं How Web API does parameter binding पर आया और पता चला कि वेब एपीआई जटिल प्रकारों के लिए मॉडल बाइंडर्स के बजाय फॉर्मेटर्स का उपयोग करता है। लिंक्ड ब्लॉग पोस्ट मेरे एक्शन पैरामीटर पर मॉडलबिन्डरएट्रिब्यूट का उपयोग करने की सिफारिश करता है, लेकिन वह विशेषता केवल पैरामीटर के रूप में एक प्रकार स्वीकार करती है। हालांकि, मेरा कस्टम मॉडल बाइंडर एक खाली कन्स्ट्रक्टर नहीं रखता है (इसे एकता कंटेनर की आवश्यकता होती है), इसलिए मुझे इसका एक उदाहरण पास करना होगा।

अन्य तरीकों से मैं फ़ॉर्मेटर्स के लिए निर्भरता इंजेक्शन का उपयोग कर सकता हूं। दुर्भाग्यवश, मैं उनसे अपरिचित हूं क्योंकि मैंने पहले कभी उनका उपयोग नहीं किया है।

जाने का सही तरीका कौन सा है? और मैं यह कैसे करूँ?

उत्तर

5

पर सेवा ढेर पर एक अद्भुत श्रृंखला है।

मैंने एक कस्टम फॉर्मेटर बनाने का निर्णय लिया जो एकता कॉल करता है और हल किए गए प्रकार का उपयोग करके अन्य सभी ऑपरेशन को आगे बढ़ाता है। यह बहुत सारे कोड की तरह दिखता है, लेकिन ऐसा इसलिए है क्योंकि सभी विधियों को ओवरराइट करने की आवश्यकता है ताकि प्रकार को हमेशा हल किया जा सके।

public class UnityFormatter : MediaTypeFormatter 
{ 
    private MediaTypeFormatter formatter; 

    private IUnityContainer container; 

    public UnityFormatter(MediaTypeFormatter formatter, IUnityContainer container) 
    { 
     this.formatter = formatter; 
     this.container = container; 

     foreach (var supportedMediaType in this.formatter.SupportedMediaTypes) 
     { 
      this.SupportedMediaTypes.Add(supportedMediaType); 
     } 

     foreach (var supportedEncoding in this.formatter.SupportedEncodings) 
     { 
      this.SupportedEncodings.Add(supportedEncoding); 
     } 

     foreach (var mediaTypeMapping in this.MediaTypeMappings) 
     { 
      this.MediaTypeMappings.Add(mediaTypeMapping); 
     } 

     this.RequiredMemberSelector = this.formatter.RequiredMemberSelector; 
    } 

    private Type ResolveType(Type type) 
    { 
     return this.container.Registrations.Where(n => n.RegisteredType == type).Select(n => n.MappedToType).FirstOrDefault() ?? type; 
    } 

    public override bool CanReadType(Type type) 
    { 
     return this.formatter.CanReadType(this.ResolveType(type)); 
    } 

    public override bool CanWriteType(Type type) 
    { 
     return this.formatter.CanWriteType(this.ResolveType(type)); 
    } 

    public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, HttpRequestMessage request, MediaTypeHeaderValue mediaType) 
    { 
     return this.formatter.GetPerRequestFormatterInstance(this.ResolveType(type), request, mediaType); 
    } 

    public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger) 
    { 
     return this.formatter.ReadFromStreamAsync(this.ResolveType(type), readStream, content, formatterLogger); 
    } 

    public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType) 
    { 
     this.formatter.SetDefaultContentHeaders(this.ResolveType(type), headers, mediaType); 
    } 

    public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext) 
    { 
     return this.formatter.WriteToStreamAsync(this.ResolveType(type), value, writeStream, content, transportContext); 
    } 
} 

अंत में, एप्लिकेशन कॉन्फ़िगरेशन (Global.asax Application_Start) में हमारे कस्टम फ़ॉर्मेटर को पंजीकृत करें। मैंने अपने मौजूदा एक उदाहरण के साथ सभी मौजूदा स्वरूपणों को प्रतिस्थापित करना चुना है, इसलिए मुझे सभी डेटा प्रकारों के प्रति प्रतिबिंब मिलता है।

// set up unity container, register all types 
UnityContainer container = new UnityContainer(); 
container.RegisterType<IApiRegistrationRequest, ApiRegistrationRequest>(); 

// save existing formatters and remove them from the config 
List<MediaTypeFormatter> formatters = new List<MediaTypeFormatter>(GlobalConfiguration.Configuration.Formatters); 
GlobalConfiguration.Configuration.Formatters.Clear(); 

// create an instance of our custom formatter for each existing formatter 
foreach (MediaTypeFormatter formatter in formatters) 
{ 
    GlobalConfiguration.Configuration.Formatters.Add(new UnityFormatter(formatter, container)); 
} 
2

मैं आपको सेवा ढेर http://www.servicestack.net/

इसकी पर एक नज़र मिला है एक ही सभी के रूप में asp.net-WebAPI डिजाइन के आसपास है, लेकिन यह आईओसी की तरह उपहार यह में शामिल किया हुआ है।

यह वही अब मैं के साथ आया था और यह काम करता है http://pluralsight.com/training/Courses/TableOfContents/service-stack

+0

धन्यवाद, यह दिलचस्प लग रहा है, लेकिन मैं अभी तकनीक को आसानी से नहीं बदल सकता। – Chris