2014-10-07 66 views
1

我尝试提取一些操作与这样一些附加的属性的接口:接口用于从基类派生的其他属性

基实体类别:

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 interface IMyClassRepository 
{ 
    void Create(MyBaseClass param); 
    void Update(MyBaseClass param); 
} 

,混凝土类就应该是这样的:

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); 
    } 
} 

UPDATE

我将创建IMyClassRepository使用Factory这样的:

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); 
    } 
} 

的问题是如何创建的IMyClassRepositoryClassBClassC附加属性的实现?

+0

也许继承不是这里的解决方案,如果他们都是不同的。 – 2014-10-07 02:25:47

+0

'void Create(MyBaseClass param);'?你能解释一下这种方法应该做什么吗? (通常'Create'会返回刚刚创建的东西,但在您的设计中并非如此)。 – 2014-10-07 02:26:37

+0

@JustinPihony但他们有相同的实体和相同的操作。 – reptildarat 2014-10-07 02:26:42

回答

2

如果我理解正确,您正在尝试设计类似于存储库模式的东西?如果是这样的话,你可以为你的所有实体创建一个存储库实现。对于这一点,你需要创建一个通用接口与您的实体的具体实现工程...

public interface IMyClassRepository<T> where T : MyBaseClass 
{ 
    T Get(int id); 
    void Create(T param); 
    void Update(T param); 
} 

然后建立这个资料库为每个实体的实现......

public ClassARepo : IMyClassRepository<ClassA>{...} 

而且那么你可以创建一个工厂对象,即时为这些具体实现服务。喜欢的东西...

var repository = RepositoryFactory.Resolve<ClassB>(); 
ClassB entity = repository.Get(234); 
entity.entityA = "new value"; 
repository.Update(entity); 

你甚至不用自己实现它,如果您使用的是d/I容器,比如温莎城堡,在这里您可以通过定义配置文件实现和服务,甚至交换他们没有必须重新编译整个应用程序。

+0

我更新我的问题。希望你能更清楚地帮助我:) – reptildarat 2014-10-07 03:00:04

+0

@reptildarat对于同样的问题,它完全一样的答案。每次需要存储库实例时,必须创建一个工厂对象的实例,这很丑陋。至少你应该让你的'CreateInstance'方法成为一个静态方法......或者让工厂对象成为一个单独对象......或者甚至更好地使用一个依赖注入容器,比如温莎城堡来避免那些永远不断增长的'switch'案例 – Leo 2014-10-07 03:07:36

+0

@reptildarat不用说有一个'enum'来决定返回什么类型的实体太没用。这就是泛型适用于在运行时推断底层数据类型的原因。你有没有想过当你需要项目中的另一个实体时会发生什么?这意味着另一个'enum'值和另一个'swicth ... case' ...这是一个巨大的设计问题,因为自从.Net Framework 2.0以来,有更好的选择... GENERICS – Leo 2014-10-07 03:09:31