C# 具有从基类派生的附加属性的接口
我尝试将一些操作提取到具有以下附加属性的接口中: 基本实体类:C# 具有从基类派生的附加属性的接口,c#,inheritance,design-patterns,interface,abstract-class,C#,Inheritance,Design Patterns,Interface,Abstract Class,我尝试将一些操作提取到具有以下附加属性的接口中: 基本实体类: public enum MyClassEnum { classA, classB, classC } public abstract class MyBaseClass { public string entityA { get;set; } public int entityB { get; set; } } 然后我有一个从MyBaseClass派生的类: public class Cl
public enum MyClassEnum
{
classA,
classB,
classC
}
public abstract class MyBaseClass
{
public string entityA { get;set; }
public int entityB { get; set; }
}
然后我有一个从MyBaseClass派生的类:
public class ClassA : MyBaseClass{}
public class ClassB : MyBaseClass
{
public string AnotherEntity { get; set; }
}
public class ClassC : MyBaseClass
{
public string AnotherEntity2 { get; set; }
public string AnotherEntity3 { get; set; }
}
我尝试有这样一个界面(这是我到目前为止得到的):
混凝土等级应该是这样的:
public class ClassBRepository : IMyClassRepository
{
private readonly BaseRepository _baseRepository;
public ClassBRepository
{
_baseRepository = new BaseRepository();
}
public void Create(MyBaseClass param)
{
// will use automapper to do the mapping
var theClassB = MyBaseClass.TranslateTo<ClassB>();
// How i can design the interface that accept additional Property on class B?
// last save the operation to DB..
_baseRepository.Save(theClassB);
}
}
public class MyClassFactory
{
public IMyClassRepository CreateInstance(MyClassEnum param)
{
switch(param)
{
case MyClassEnum.ClassA
{
return new ClassARepository;
}
case MyClassEnum.ClassB
{
return new ClassBRepository;
}
case MyClassEnum.ClassC
{
return new ClassCRepository;
}
}
}
}
public class ConcreteOperationClass
{
private IMyClassRepository _myClass;
public ConcreteOperationClass(MyClassEnum param)
{
_myClass = new MyClassFactory().CreateInstance(param);
}
public void CreateMyClass(MyBaseClass param, // this should be a parameter class B or Class C needed)
{
_myClass.Create(param, // additional property for classB or classC);
}
}
最后有这样的操作课:
public class ClassBRepository : IMyClassRepository
{
private readonly BaseRepository _baseRepository;
public ClassBRepository
{
_baseRepository = new BaseRepository();
}
public void Create(MyBaseClass param)
{
// will use automapper to do the mapping
var theClassB = MyBaseClass.TranslateTo<ClassB>();
// How i can design the interface that accept additional Property on class B?
// last save the operation to DB..
_baseRepository.Save(theClassB);
}
}
public class MyClassFactory
{
public IMyClassRepository CreateInstance(MyClassEnum param)
{
switch(param)
{
case MyClassEnum.ClassA
{
return new ClassARepository;
}
case MyClassEnum.ClassB
{
return new ClassBRepository;
}
case MyClassEnum.ClassC
{
return new ClassCRepository;
}
}
}
}
public class ConcreteOperationClass
{
private IMyClassRepository _myClass;
public ConcreteOperationClass(MyClassEnum param)
{
_myClass = new MyClassFactory().CreateInstance(param);
}
public void CreateMyClass(MyBaseClass param, // this should be a parameter class B or Class C needed)
{
_myClass.Create(param, // additional property for classB or classC);
}
}
问题是如何使用
ClassB
或ClassC
中的附加属性创建IMyClassRepository
的实现?如果我理解正确,您是在尝试设计类似于存储库模式的东西吗?如果是这样,您可以为所有实体创建一个存储库实现。为此,您需要创建一个通用接口,该接口与实体的具体实现一起工作
public interface IMyClassRepository<T> where T : MyBaseClass
{
T Get(int id);
void Create(T param);
void Update(T param);
}
公共接口IMyClassRepository,其中T:MyBaseClass
{
T Get(int-id);
无效创建(T参数);
无效更新(T参数);
}
然后为每个实体创建此存储库的实现
public ClassARepo : IMyClassRepository<ClassA>{...}
public ClassARepo:IMyClassRepository{…}
然后,您可以创建一个工厂对象,动态地为这些具体实现提供服务。类似于
var repository = RepositoryFactory.Resolve<ClassB>();
ClassB entity = repository.Get(234);
entity.entityA = "new value";
repository.Update(entity);
var repository=RepositoryFactory.Resolve();
ClassB entity=repository.Get(234);
entity.entityA=“新值”;
更新(实体);
如果您使用Windsor Castle这样的D/I容器,您甚至不必自己实现它,您可以通过配置文件定义实现和服务,甚至可以在不必重新编译整个应用程序的情况下交换它们。如果它们完全不同,那么继承可能不是解决方案。
void Create(MyBaseClass参数)代码>?你能解释一下这个方法的作用吗?(通常,Create
会返回它刚刚创建的东西,但在您的设计中不是这样)。@JustinPihony,但它们有相同的实体,和相同的操作。@AlexeiLevenkov它应该保存一些记录。如果该方法需要一个ClassB属性,那么它将需要一个ClassB作为参数。@LadderDarat对同一个问题的回答完全相同。每次需要存储库实例时,都必须创建factory对象的实例,这很难看。至少你应该把你的CreateInstance
方法变成一个静态方法…或者把工厂对象变成一个单例对象…或者更好地使用一个依赖注入容器,比如Windsor Castle,以避免那些永远增长的开关
cases@reptildarat不用说,使用enum
来确定返回的实体太无用了。泛型就是用来在运行时推断底层数据类型的。你有没有想过当你的项目中需要另一个实体时会发生什么?这意味着另一个enum
值和另一个switch…case
…这是一个巨大的设计问题,因为自.Net Framework 2.0以来,您有了更好的选择…generics但是,我需要为每个实体在ConcreteOperationClass上创建“create”,对吗?我的目标不仅仅是接受所有参数(classA,classB,classC)的一种方法,我不太确定这是什么意思,但温莎城堡的美妙之处在于你根本不需要创建任何东西。它解决了基于配置文件的依赖关系,DI/IoC是一个方面(因为我不能在ASMX项目上“轻松地”使用它),我明白你的观点。我可以将其提取到通用存储库模式。