【问题标题】:C# Interfaces implementationC#接口实现
【发布时间】:2013-01-31 10:08:10
【问题描述】:

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

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

【问题讨论】:

  • 因为(我刚刚更新了帖子)我想在基类中包装一些基本相同的公共方法(Save())但引用不同的 DAL 存储库..希望你可以理解我..我对 C# 和英语都有问题 ;)

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


【解决方案1】:

首先我认为你和你的成员发生了名字冲突 IRepository rep.

尝试使用 DAL.IRepository rep

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

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

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

或者,您可以使用

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

【讨论】:

    【解决方案2】:
    public Service()
            : base(new DAL.Repository())
        {
               rep = (Repository)base.repository;
    
        }
    

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

    【讨论】:

    • 我为我的问题感到羞耻.. 太简单了!可能我向谷歌提出了错误的问题.. 非常感谢您
    • 答案解决了您的问题(尽管没有异常处理 - 可以使用 asis 来检查您传入的 IRepository 是否是存储库),但这有点打破我的想法重新尝试首先注入接口。您可能会更好地将“添加”添加到 IRepository,或者重新考虑您的设计。
    • 嗯,没有什么 2 b 感到羞耻,你在正确的道路上。除了我不会用铸造的方式来做。我想当你制作更多的存储库时你会明白的。现在,因为你只有一个 IRepository 的实现,所以一切似乎都很好。当您执行 IRepository 4-5 次时,您将看到此设计的错误。
    • 正是上一篇文章所说的。在调用 add 方法之前,您必须检查 typeof(obj) = "Repository",因为它是一个较新的实现,并且不适用于其他实现。但我不认为这是一个设计缺陷。这只是在设计了多个类之后我们都必须决定的事情,现在推断任何事情都为时过早。
    • 你绝对 Save and Dispose 就足够了,并且是所需的最小绑定实现。如果您在 IRepository 中添加了一个 Add ,那么所有其他实现都必须实现 Add ,这不是您想要的。老实说,你可能有一个 DeleteRepository、CloneRepository、MultiplyRepository、GrowRepository,它们不需要添加,但它们都需要实现 Save 和 Dispose.. 所以你必须做 typeof(IRepository) = "AddRepository" call Add, typeof( IRepository ob) = "CloneRepository" 调用 Clone,typeof(IRepository obj) = "DeleteRepository" 调用 Delete.. 在 Impl 之外。
    【解决方案3】:

    看到您的主要问题是缺乏对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 公开的所有方法,因为它是使用泛型进行强类型化的。希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-15
      • 2012-02-01
      • 1970-01-01
      相关资源
      最近更新 更多