【发布时间】:2014-06-19 05:23:24
【问题描述】:
所以我有这个域模型:
public abstract class PrimaryKey
{
public Guid Id {get;set;}
}
public class MyEntity : PrimaryKey
{
public string StringProperty {get;set;}
public MyEntity2 MyEntity2 {get;set;}
}
public class MyEntity2 : PrimaryKey
{
public string StringProperty {get;set;}
}
我想为它们提供接口,以便我可以将它们与注入的服务一起使用。我不能只在服务核心项目中引用领域模型,因为在我看来这是落后的。
所以我想到了这个:
public interface IPrimaryKey
{
Guid Id {get;set;}
}
public interface IMyEntity : IPrimaryKey
{
string StringProperty {get;set;}
IMyEntity2 MyEntity2 {get;set;}
}
public interface IMyEntity2 : IPrimaryKey
{
string StringProperty {get;set;}
}
所以现在我有了具体的类和接口。但是我的接口现在如何影响我的具体类,当然引用IMyEntity 将意味着在具体类中我必须定义Id 属性,但我真的希望我的抽象类这样做以节省时间。
以下是我得到的:
public class MyEntity : IMyEntity
{
public Guid Id {get;set;}
public string StringProperty {get;set;}
public IMyEntity MyEntity2 {get;set;}
}
如何使用抽象类?它仍然有效吗?还是我必须实现另一种编程方法?
我认为这可能会起作用:
public class MyEntity : PrimaryKey, IMyEntity
{
// etc, but no Id field this time
}
这将如何在我的存储库中工作,我使用泛型接口:
public interface IRepository
{
Task<List<T>> AllAsync<T>();
Task<T> FindAsync<T>(Expression<Func<T, bool>>[] params);
}
public class Repository : IRepository
{
public Task<List<T>> AllAsync<T>()
{
return _dbContext.Set<T>().ToListAsync();
}
// etc
}
会有影响吗?
我这样做是因为我想将服务核心和域模型抽象到一个新项目中,并在 ASP.NET 前端和 WCF 服务之间使用这个项目。该服务目前只需要使用一个实体,但以后可能会增加。
【问题讨论】:
-
在这些示例中滥用继承是在挖一个大坑。
-
是的,我必须同意@KeithPayne 这个解决方案似乎是过度设计的,你为什么说“我不能只在服务核心项目中引用域模型,因为在我看来是落后的”,如果服务核心与域交互,我看不出有什么问题,IMO 将是一个更容易实现和维护的解决方案
-
另一种想法是,还有其他方法可以优雅地处理重用代码,这些代码适用于包含一个或多个在集合中必须唯一的属性的模型。我以前做过这种紧密绑定的自我验证实体的事情。它最终会迅速退化为一种反模式,在这种模式下,您会花费更多精力编写代码来解决预期的问题,但不会让您更接近交付您的产品。
-
@KeithPayne 你能否详细说明我如何滥用继承
-
经验法则:继承适用于
Is-A,而不是Has-A关系。class MyEntity属于第二种类型 -MyEntity有一个 主键。您希望跨具有Guid Id属性的对象重复使用的代码不需要位于基类中,但可以位于旨在处理IPrimaryKey对象的不同类中。接口的继承问题较少。
标签: c# asp.net-mvc entity-framework wcf