2011-05-20 25 views
6

Bir RESTful hizmet oluşturmak için yeni WCF Web API'sini kullanıyorum ve hizmetimde, hedef kaynağı tanımlayacak olan URI'nin bir bölümüne sahibim. Sözleşmenin tüm yöntemleri (neredeyse). Ben e-Ticaret ile uğraşan bir kullanıcı hizmeti ve gibi görünebilir Örneğin,: Ben sürekli null organizasyonunu ve testi yük varsaWCF Web API Birden Çok Yöntemde Bulunan UriTemplate Öğeleri

[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. 
    } 
} 

, bu kodumu batağa saplanmak ve çok KURU almayacaktır. (Bu yüzden DRY'yi hecelemeye karar verdim ...) Yapmak istediğim, {KuruluşAdı} URI'ye dahil edildiğinde ve bir WebFaultException komutunu attığında oluşturulan bir MyUserService sınıfında bir özellik yüklemektir. Bu URI dışında olduğu için, bunu başarmanın en iyi yolu ne olurdu?

DÜZENLEME: ilginizi çekebilir olanlar için

, burada ben ile geldi HttpOperationHandler bir örnektir. Bunu kapsayan bir sürü bilgi yok gibi gözüküyor. Ben de WCF Web Api paketi ile gelen Processors hakkında daha fazla bilgi buldum ve bu tür bir şey daha iyi yerine HttpOperationHandlers yerini alacak gibi görünüyor ve kullanımı daha kolay görünüyor.

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; 
    } 
} 

(Bu. Bir örnek ı bulmak zor bulduğumuz bazı şeyleri kapsayacak şekilde. Benim uygulamada biraz farklı o kadar yazdım adildir) Sonra ben (Global.asax onu kadar Tel) IoC için Ninject kullanarak:

// 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); 
    } 
} 

Ve işte benim Service içinde:

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

İşlemci sadece HttpOperationHandler –

+0

@Darrel Miller için eski addır - teşekkürler! Diğer tüm "WCF REST" bağlantıları ile karışır tüm değişiklikler ve bilgi eksikliği (anlaşılabilir) ile devam etmeye çalışıyorum oldukça zor hale getirir. Bunu yakaladığın için teşekkürler! –

+0

OperationHandler'da güzel iş! –

cevap

2

Bu OperationHandlers için tam olarak ne olduğunu. URI parametresini, operasyonda bir parametre olarak kabul edebileceğiniz güçlü bir şekilde yazılmış bir nesneye dönüştüren tek bir OperationHandler yaratırsınız.

İlgili konular