2011-05-20 10 views
6

मान लें कि मैं एक नई सेवा के लिए नई डब्ल्यूसीएफ वेब एपीआई का उपयोग कर रहा हूं और मेरी सेवा में, मेरे पास यूआरआई का एक अनुभाग है जो लक्ष्य संसाधन का वर्णन करेगा, लेकिन इसका उपयोग किया जाता है अनुबंध के सभी तरीकों (लगभग) पर। उदाहरण के लिए, अगर मैं एक उपयोगकर्ता सेवा है कि ई-कॉमर्स के साथ संबंधित है और की तरह लग रहे हो सकता है:डब्ल्यूसीएफ वेब एपीआई यूरी टेम्पलेट तत्व एकाधिक तरीकों से मिले

[ServiceContract] 
public class MyUserService 
{ 
    private MyUserRepository _UserRepo; 
    private MyOrganizationRepository _OrgRepo; 

    [WebGet (UriTemplate = "{OrganizationName}/Users")] 
    public IEnumerable<User> GetUsers (string OrganizationName) 
    { 
     IEnumerable<User> Users = null; 
     var Organization = _OrgRepo.GetOrgByName (OrganizationName); 

     if (Organization != null) 
     { 
      Users = Organization.GetUsers(); 
     } 
     else 
     { 
      throw new WebFaultException<string> ("Organization not found.", HttpStatusCode.NotFound); 
     } 

     return Users; 
    } 

    [WebInvoke (UriTemplate = "{OrganizationName}/Users", /*yada...yada...yada*/)] 
    public User AddNewUser (string OrganizationName, User User) 
    { 
     // Find the organization, like above, and throw if null. 
    } 
} 

मैं लगातार अशक्त के लिए संगठन और परीक्षण लोड करने के लिए है, तो यह नीचे मेरी कोड दलदल और बहुत शुष्क नहीं है जाएगा। (इसलिए DRY को स्पेल करने का लुत्फ उठाया गया ...) मैं जो करना चाहता हूं वह MyUserService क्लास में एक संपत्ति लोड करना है जो यूआरआई में {OrganizationName} शामिल है और अन्यथा WebFaultException को फेंक देता है। क्योंकि यह यूआरआई के अलावा है, इसे पूरा करने का सबसे अच्छा तरीका क्या होगा?

संपादित करें:

उन है कि रुचि हो सकती है के लिए, यहाँ HttpOperationHandler मैं के साथ आया था का एक उदाहरण है। इसमें शामिल होने वाली पूरी जानकारी नहीं है। मुझे Processors के बारे में अधिक जानकारी मिली है जो डब्ल्यूसीएफ वेब एपी सूट के साथ आ रहा है और ऐसा लगता है कि वे इस तरह की चीज को को HttpOperationHandlers को बेहतर तरीके से संभालेंगे और ऐसा लगता है कि उनका उपयोग करना आसान हो सकता है। (यह सिर्फ एक के लिए-उदाहरण कुछ चीजें मैं मुश्किल पाया कवर करने के लिए। मैं इसे थोड़ा अलग लिखा था अपने आवेदन में है।)

using Microsoft.ApplicationServer.Http.Dispatcher; // For HttpOperationHandler 
using Microsoft.ApplicationServer.Http.Description; // For HttpOperationHandlerFactory 

public class OrganizationHandler : HttpOperationHandler<string, Organization> 
{ 
    private Repository<Organization> _OrganizationRepository; 

    public OrganizationHandler (UnitOfWork Work) 
     : base ("OrganizationName") 
    { 
     _OrganizationRepository = Work.Organizations; 
    } 

    public override Organization OnHandle (string OrganizationName) 
    { 
     var Result = _OrganizationRepository 
         .Get (O => O.UrlSafeName.Equals (OrganizationName, 
               StringComparison.InvariantCultureIgnoreCase)); 

     if (Result == null) 
     { 
      throw new WebFaultException<string> ("Organization not found."); 
     } 

     return Result; 
    } 
} 

public class OrganizationHandlerFactory : HttpOperationHandlerFactory 
{ 
    private UnitOfWork _Work; 

    public OrganizationHandlerFactory (UnitOfWork Work) 
    { 
     _Work = Work; 
    } 

    protected override Collection<HttpOperationHandler> OnCreateRequestHandlers 
     (ServiceEndpoint endpoint, HttpOperationDescription operation) 
    { 
     var Collection = base.OnCreateRequestHandlers (endpoint, operation); 

     if (operation.InputParameters.Any (IP => IP.Type.Equals (typeof (Organization)))) 
     { 
      var Binding = endpoint.Binding as HttpBinding; 

      if (Binding != null) 
      { 
       Collection.Add (new OrganizationHandler (_Work)); 
      } 
     } 

     return Collection; 
    } 
} 

और फिर Global.asax में यह तार अप करने के लिए (मैं कर रहा हूँ आईओसी के लिए) का उपयोग कर Ninject:

// Add this reference to get the MapServiceRoute<T> extension 
using Microsoft.ApplicationServer.Http.Activation; 

public class Global : HttpApplication 
{ 
    protected void Application_Start (object sender, EventArgs e) 
    { 
     var Kernel = BuildKernel(); 

     var Config = HttpHostConfiguration.Create() 
      .SetOperationHandlerFactory 
       (Kernel.Get (typeof (OrganizationHandlerFactory)) as OrganizationHandlerFactory) 
      .SetResourceFactory (new NinjectResourceFactory (Kernel)); 


     RouteTable.Routes.MapServiceRoute<OrganizationService> ("Organizations", Config); 
    } 

    protected IKernel BuildKernel() 
    { 
     IKernel Kernel = new Ninject.StandardKernel(); 

     // Load up the Kernel 

     return Kernel; 
    } 
} 

public class NinjectResourceFactory : IResourceFactory 
{ 
    private readonly IKernel _Kernel; 

    public NinjectResourceFactory (IKernel Kernel) 
    { 
     _Kernel = Kernel; 
    } 

    public object GetInstance (Type serviceType, InstanceContext instanceContext, HttpRequestMessage request) 
    { 
     return Resolve (serviceType); 
    } 

    public void ReleaseInstance (InstanceContext instanceContext, object service) 
    { 
     throw new NotImplementedException(); 
    } 

    private object Resolve (Type type) 
    { 
     return _Kernel.Get (type); 
    } 
} 

और यहाँ यह मेरी सेवा में है:

[ServiceContract] 
[ServiceBehavior (InstanceContextMode = InstanceContextMode.PerCall)] 
public class OrganizationService 
{ 
    [WebGet (UriTemplate = "{OrganizationName}/Products")] 
    public IEnumerable<Product> GetProducts (Organization Organization) 
    { 
     return Organization.Products; 
    } 
} 
+0

प्रोसेसर HttpOperationHandler –

+0

@ डैरल मिलर के लिए पुराना नाम है - धन्यवाद! मैं सभी बदलावों और सूचना की कमी (समझने योग्य) के साथ बनाए रखने की कोशिश कर रहा हूं जो अन्य "डब्ल्यूसीएफ आरईएसटी" लिंक के साथ भी मिश्रण करता है, यह बहुत कठिन बनाता है। इसे पकड़ने के लिए धन्यवाद! –

+0

ऑपरेशन हैंडलर पर अच्छी नौकरी! –

उत्तर

2

यह वह जगह है वास्तव में क्या OperationHandlers के लिए कर रहे हैं। आप एक एकल ऑपरेशन हैंडलर बनाते हैं जो यूआरआई पैरामीटर को दृढ़ता से टाइप की गई वस्तु में परिवर्तित करता है जिसे आप ऑपरेशन पर पैरामीटर के रूप में स्वीकार कर सकते हैं।

संबंधित मुद्दे