C#接口实现

时间:2013-01-31 10:08:11

标签: c# interface n-tier-architecture multi-tier

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

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#中我希望避免复杂性是可能的,至少我会更专业:)

3 个答案:

答案 0 :(得分:3)

首先,我认为你的名字与你的成员有冲突         IRepository rep.

尝试使用         DAL.IRepository rep

您收到错误的原因是您已将“添加”定义为“存储库”所特有的内容。您的成员变量是一个“IRepository”,允许您将实现“IRepository”的任何内容放到其上。

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

如果您需要在任何存储库上调用add,请将其添加到界面。否则,您需要确定该成员是否应该是IRepository或Repository。

或者,您可以使用

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

答案 1 :(得分:1)

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

    }

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

答案 2 :(得分: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公开的所有方法,因为它是通用的强类型。希望这会有所帮助。