我有一个相对简单的系统,就本问题而言,它基本上包括三个部分:模型、仓库和应用程序代码。
核心是模型。我们使用一个简单的编造示例:
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);
}
}
但编译错误仍然存在。有没有办法实现我想要的效果?我对设计非常灵活,所以如果我的架构方法不正确,我可以退后一步并改变大局。
BaseModel<T>
没有实现ISaveableModel<T>
。你试过了吗? - agent-j