У меня довольно простая система, и для целей этого вопроса, по сути, есть три части: Модели, Репозитории, Код приложения.
В основе лежат модели.Давайте использовать простой надуманный пример:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
В этом же проекте используется универсальный интерфейс хранилища.Самое простое:
public interface IRepository<T>
{
T Save(T model);
}
Реализации этого интерфейса находятся в отдельном проекте и внедрены в StructureMap.Для простоты:
public class PersonRepository : IRepository<Person>
{
public Person Save(Person model)
{
throw new NotImplementedException("I got to the save method!");
// In the repository methods I would interact with the database, or
// potentially with some other service for data persistence. For
// now I'm just using LINQ to SQL to a single database, but in the
// future there will be more databases, external services, etc. all
// abstracted behind here.
}
}
Итак, в коде приложения, если бы я хотел сохранить модель, я сделал бы это:
var rep = IoCFactory.Current.Container.GetInstance<IRepository<Person>>();
myPerson = rep.Save(myPerson);
Достаточно просто, но кажется, что это можно автоматизироватьмного.Этот шаблон сохраняется во всем коде приложения, поэтому я хочу создать единый универсальный Save()
для всех моделей, который будет просто кратким вызовом приведенного выше кода приложения.Таким образом, нужно будет только позвонить:
myPerson.Save();
Но я не могу найти способ сделать это.Может быть, это обманчиво просто, и я просто не смотрю на это с правильной точки зрения.Сначала я попытался создать пустой интерфейс ISaveableModel<T>
и намеревался сделать так, чтобы каждая «способная к сохранению» модель реализовывала его, затем для одного общего метода Save()
у меня было бы расширение интерфейса:
public static void Save<T>(this ISaveableModel<T> model)
{
var rep = IoCFactory.Current.Container.GetInstance<IRepository<T>>();
model = rep.Save(model);
}
Но он говорит мне, что rep.Save(model)
имеет недопустимые аргументы.Кажется, что это не связывает вывод типа, как я надеялся.Я попробовал аналогичный подход с классом BaseModel<T>
, от которого наследуются модели:
public class BaseModel<T>
{
public void Save()
{
this = IoCFactory.Current.Container.GetInstance<IRepository<T>>().Save(this);
}
}
Но ошибка компилятора та же.Есть ли способ добиться того, чего я пытаюсь достичь?Я очень гибок в дизайне, поэтому, если я что-то не так делаю на архитектурном уровне, тогда у меня есть возможность сделать шаг назад и изменить общую картину.