Наследование операций REST WCF - PullRequest
1 голос
/ 24 ноября 2011

Я играю с WCF REST в .NET 4.0, и в итоге мне захотелось выяснить, возможно ли реализовать какую-то следующую идею?

У меня есть очень простой набор POCO противПроект EF 4.1 CF.Все они наследуются от базового Entity класса (с единственной целью определения PK).

public abstract Entity {
    public int Id { get; set; }
}

Теперь, по большей части, я буду иметь отдельные операции для функциональности CRUD для каждогомоих сущностей (или агрегатов, в более крупных системах, я полагаю).

например,

[ServiceContract]
public class UserService {
    [OperationContract]
    public void Add(User user) {
        // commit to EF
        fooContext.Users.Add(user);
        fooContext.SaveChanges();
    }
}

Теперь, это в первую очередь просто для удобства, но я думал, что что-то подобное будет действительноудобно:

[ServiceContract]
public abstract class BaseCrudService<T> where T : Entity {
    [OperationContract]
    public void Add(T entity) {
        // commit to EF via generic methods
        fooContext.Set<T>().Add(entity);
        fooContext.SaveChanges();
    }
}

public class UserService : BaseCrudService<User> {
    // blah
}

... что теоретически позволило бы мне получить доступ к этой операции через http://<root>/userservice/add и работать с ней так, как я ожидал, за исключением того, что я не могу унаследовать ServiceContract -декорированныйкласс, так что нет никакой надежды на автоматическое каскадное функционирование вплоть до самих конечных точек.

Мне было интересно: есть ли способ как-то это сделать? Я знаю это наследование (таким образом)не будет сокращать, но есть ли другие способы сделать это?Повторение одинаковых фрагментов кода в нескольких сервисных операциях звучит как то, о чем кто-то мог подумать раньше и придумал более чистый способ реализации.

Ответы [ 2 ]

3 голосов
/ 24 ноября 2011

Вы можете использовать интерфейс в качестве контракта на обслуживание, поэтому вы можете сделать следующее:

public abstract class BaseCrudService<T> where T : Entity
{        
    public void Add(T entity)
    {
        // commit to EF via generic methods
        fooContext.Set<T>().Add(entity);
        fooContext.SaveChanges();
    }
}

public class UserService : BaseCrudService<User>, IUserService
{
    // No need to put anything in here, just need a constructable class
}

// You would need to create an interface for each service you expose like so
[ServiceContract]
public interface IUserService
{
    [OperationContract]
    void Add(User entity);
}

Сделайте это так, и вам не нужно дублировать какой-либо код.

Для полноты вот конфиг:

<system.serviceModel>
  <bindings />
  <services>
    <service name="Demo.UserService">
      <endpoint address=""
                behaviorConfiguration="json"
                binding="webHttpBinding"
                name="jsonEndpoint"
                contract="Demo.IUserService" />
    </service>
  </services>
  <behaviors>
    <endpointBehaviors>
      <behavior name="json">
        <webHttp/>
      </behavior>
    </endpointBehaviors>
  </behaviors>
</system.serviceModel>
1 голос
/ 24 ноября 2011

AFAIK, использование дженериков в сервисных операциях невозможно.: (

Вы можете добавить обертку к вашему public void Add(T entity) в UserService ... но это нарушит цель вашей основанной на генериках фреймворка.

...