2013-01-31 57 views
2

我不知道如何正确管理C#中的接口。我的目标是为我的业务层服务创建一个抽象类,它具有一些调用不同DAL存储库方法的常用方法(如Save(),Dispose())。我想避免在我所有的服务类似重复:C#接口实现

public Save() 
{ 
    repository.Save(); 
} 

我有类似的情景:

接口

namespace Common 
{ 
    public interface IRepository 
    { 
     void Save; 
     void Dispose; 
    } 
} 

DAL

namespace DAL 
{ 
    public Repository : IRepository 
    { 
     public void Save() {}; 
     public void Dispose() {}; 
     public void Add() {} 
    } 
} 

BL

namespace BL 
{ 
    public abstrac BaseService 
    { 
     protected IRepository repository; 
     protected BaseService(IRepository repo) 
     { 
      repository = repo; 
     } 

     public Save() 
     { 
      repository.Save(); 
     } 
    } 

    //... 

    //Tentative 1 
    public Service : BaseService 
    { 
     private Repository rep; 

     public Service() 
      : base(new DAL.Repository()) 
     { 
      rep = base.repository; // ERROR: cannot convert IRepository to Repository 
     } 
    } 
} 

我也试过这样:

//Tentative 2 
public Service : BaseService 
{ 
    private IRepository rep; 

    public Service() 
     : base(new DAL.Repository()) 
    { 
     rep = base.repository; // OK 
    } 

    public void Add() 
    { 
     rep.Add() // ERROR: IRepository doesn't contain a definition for 'Add' 
    } 
} 

我知道我可以在接口定义所有我想要使用的方法,但我将不得不管理很多问题与泛型类型,正如你应该从我了解的问题,我在C#相当新的,我希望能避免复杂性是可能的,utill我会更加的专家至少:)

+0

因为(我刚刚更新了这篇文章)我想在基类中包装一些基本上相同的Saves()方法,但是引用了不同的DAL存储库..希望你能理解我..我对C#和英语都有问题;) – Davide

回答

1
public Service() 
     : base(new DAL.Repository()) 
    { 
      rep = (Repository)base.repository; 

    } 

这样你将得到Add()服务,它不是IRepository的一部分,而是扩展类中的一个更新的实现。

+0

我很惭愧我的问题..这很容易!可能我向谷歌提出了错误的问题..非常感谢你 – Davide

+1

答案解决了你的问题(虽然没有异常处理 - 可以使用as或is来检查你在IRepository中传递的是否是一个Repository),但它是一种打破了我认为你想要首先注入接口的想法。您可能会更好地向IRepository添加'添加',或者可能重新考虑您的设计。 – Cashley

+0

那么在正确的道路上,没有什么是耻辱的。除了我会以演员的方式去做。我想你会明白你什么时候制作更多的信息库。现在,因为你只有一个IRepository的实现,一切似乎都可以。当你实现IRepository 4-5次时,你会看到这个设计的错误。 – user1974729

3

首先我觉得你有一个名称冲突与您成员 IRepository rep.

尝试使用 DAL.IRepository rep

,你得到一个错误的原因是,你定义“添加”为“仓库”特有的东西。你的成员变量是一个“IRepository”,允许你将任何实现“IRepository”的东西放到它上面。

仅仅因为您可以将存储库放入其中,并不意味着它上面的所有内容都将成为存储库。 (认为​​它看起来不错,手指和拇指,所有的拇指都是手指,但不是所有的手指都是拇指)

如果您需要调用添加任何存储库,然后将其添加到接口。否则,您需要确定该成员是否应该是IRepository或Repository。

或者,你可以使用

Repository myRep = rep as Repository; 
    if(rep!=null) 
    { 
     myRep.Add(); 
     ... 
     profit(); 
    } 
0

鉴于你的主要问题是缺乏无障碍的Add方法,并看到,因为这是一个相对常见的方法,无论如何,我会首先推荐它添加到您的IRepository,所以它看起来是这样的:

public interface IRepository 
{ 
    void Add(); 
    void Save(); 
    void Dispose(); 
} 

你会再实现你适当的资源库,同时从IRepository继承。现在,可以理解你可能想要访问Repository上的自定义方法。为了解决这个你可以做的是有你的BaseService接受一个通用存储库:

public BaseService<T> where T : IRepository 
{ 
    protected T repository { get; set; } 
    protected BaseService(T repo) 
    { 
     repository = repo; 
    } 
} 

然后服务应该是这样的

public UserService : BaseService<UserRepository> 
{ 
    public UserService() : base(new DAL.UserRepository()) 
    { 
     // base.Repository is now a UserRepository. 
    }  
} 

使用这种实现您的UserService将能够访问所有UserRepository公开的方法,因为它是强类型的泛型。希望这可以帮助。