Реализация службы данных WCF с использованием шаблона репозитория - PullRequest
3 голосов
/ 19 июля 2011

Мы используем шаблон репозитория в нашем приложении ASP.NET MVC 3. Это означает, что, хотя мы используем EF 4.1 Code First для доступа к данным в бэкэнде, все контроллеры MVC делают это через общий класс репозитория, а не напрямую через подкласс DbContext.

Упрощенный фрагмент кода:

public class MyEntityContext : DbContext, IMyEntityContext
{
    public IDbSet MyEntities { get; set; }
    ...
}

public class MyEntityRepository : IMyEntityRepository
{
    private IMyEntityContext _context;

    public IQueryable<MyEntity> MyEntities
    {
        return _context.MyEntities;
    }
    ...
}

public class MyEntityController : Controller
{
    private MyEntityRepository _repository;
    ...
}

Мы используем интерфейсы и внедрение зависимостей для каждой зависимости. Работает нормально. Выглядит хорошо, не так ли? Но теперь для предостережения:

Мы также предоставляем Службу данных WCF (CTP, поддерживающий Code First) для доступа к объектам. Мы хотим использовать репозиторий и в этом сервисе. Но это кажется сложным. При прямом использовании MyEntityContext услуга выглядит следующим образом:

public class MyEntityService : DataService<MyEntityContext>
{
    public static void InitializeService(DataServiceConfiguration config)
    {
        config.SetEntitySetAccessRule("MyEntities", EntitySetRights.All);
    }
}

Но когда я пытаюсь заменить MyEntityContext на хранилище, возникают две проблемы:

  1. Тип, указанный для универсального DataService<..>, должен быть классом с конструктором по умолчанию, который нарушает симпатичный дизайн по контракту и дизайн внедрения зависимостей.
  2. Даже кажется, что предоставленный тип должен быть классом DbContext: я пробовал и использовал MyEntityRepository вместо этого, но не смог (см. Подробности).

Кажется, я потерян ... Кто-нибудь может вернуть меня на правильный путь?


подробности:

Мой первый путь был:

public class MyEntityService : DataService<MyEntityRepository>
{
    ...

Однако при вызове службы происходит сбой со следующим сообщением об ошибке:

Сервер обнаружил ошибку при обработке запроса. Сообщение об исключении: «В типе контекста данных« MyEntityRepository »имеется верхнее свойство IQueryable« MyEntities », тип элемента которого не является типом объекта. Убедитесь, что свойство IQueryable относится к типу сущности, или укажите атрибут IgnoreProperties для типа контекста данных, чтобы игнорировать это свойство. '.

Я попытался выполнить следующие шаги, чтобы исправить это, но не избавился от этого сообщения об ошибке:

  • Добавление [DataServiceKey("MyEntityId")] в MyEntity, где MyEntityId - правильное ключевое свойство сущности.
  • Замена типа Repository.MyEntities на IDbSet вместо IQueryable.

Кстати: следующие сообщения не дубликаты:

Ответы [ 2 ]

3 голосов
/ 20 июля 2011

Почему вы хотите использовать репозиторий?У вас есть контекст, так что используйте его.Не создавайте луковую архитектуру только потому, что вы хотите использовать шаблон.Служба данных WCF уже сама обрабатывает все, что вам нужно.К сожалению, иногда он предлагает даже больше (например, перехватчики).

Используя пользовательский репозиторий, вы переходите к источнику данных поставщика отражений .Если вы также планируете модифицировать свои сущности с помощью службы данных WCF, которая также относится к вашему хранилищу, поскольку поставщик отражений доступен только для чтения, если он также не реализует IUpdateable.Проверьте также правила для провайдера рефлексии .

Кстати.Службы данных WCF в .NET 4 не поддерживают DbContext напрямую (эта поддержка доступна только в CTP следующей версии), но для этого существует обходной путь .Ссылка для старой ОСАГО.В текущей версии нет свойства UnderlyingContext, но вы можете использовать IObjectContextAdapter для получения ObjectContext.

Как вы также можете видеть в последнем типе ссылки, предоставляемой службе, не требуется иметь конструктор по умолчанию- это зависит от вас, какой конструктор вы используете при создании источника данных.Если вам нужно внедрение зависимостей, вам, вероятно, придется проверить способ внедрения непосредственно в саму службу (например, здесь для Unity и обычного WCF) и использовать введенные данные в CreateDataSource.

1 голос
/ 26 ноября 2014

Вот как создать службу данных WCF с любым шаблоном, который вы используете, даже без него.

Начало работы с OData. Часть 2. Создание служб OData из любого источника данных

Просто убедитесь, что у вашей сущности, документа, модели или чего-либо еще есть свойство public int ID или эта аннотация класса, предоставленная сборкой System.Data.Services в System.Data.Services namespace:

[DataServiceKey("TheNameOfYourPrimaryKeyProperty")]

Это сделает его распознаваемым как тип сущности службой данных WCF.

Как уже отмечали другие, просто убедитесь, что добавление еще одного слоя в ваш стек является хорошим решением.

...