Реализация службы данных WCF с использованием шаблона репозитория

Мы используем шаблон репозитория в нашем приложении 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 ответа

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

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

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

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

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

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

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

[DataServiceKey("TheNameOfYourPrimaryKeyProperty")]

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

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

Другие вопросы по тегам