IoC 服务的抽象类还是接口?

发布于 2024-10-27 12:57:24 字数 1148 浏览 4 评论 0原文

我目前正在使用 IoC 在项目中提供存储库的具体实现。我读过的所有示例都使用接口作为服务的定义。但是,在阅读了 Microsoft 的建议后,建议优先使用抽象类而不是接口

我发现这与模板模式结合使用可以减少重复。例如,给一个带有属性 IsActive 的 Product 类,我可以使用存储库的接口,例如:

interface IProductRepository
{
    IEnumerable<Product> Load();
}

如果常见任务是加载活动产品,那么我需要这样做:

IEnumerable<Product> activeProducts = repository.Load().Where(x => x.IsActive);

其中repository是一个具体的实现。如果我使用一个抽象类,例如:

abstract class ProductRepository
{
    protected abstract IEnumerable<Product> LoadCore();

    public IEnumerable<Product> Load()
    {
        return LoadCore().Where(x => x.IsActive);
    }
}

那么我可以使用加载活动产品

IEnumerable<Product> activeProducts = repository.Load();

。加载产品信息的所有实现都位于派生 ProductRepository 的contete类中,因此与持久层没有耦合。如果发现存在另一个经常执行的活动,则可以将其作为非破坏性更改添加到基类中,而这是使用接口无法完成的。

使用接口而不是抽象类有什么好处吗?使用抽象类可能会遇到哪些潜在缺点?

我使用 Castle Windsor 作为 IoC 控制器和 .Net Framework 3.5。

I am currently using IoC for providing concrete implemenations of repositories in a project. All of the examples that I have read use an interface as the definition of the service. However, having read recommendations from Microsoft it is recommended to prefer abstract classes over interfaces.

I have found this useful in conjuntion with the template pattern to reduce repetition. For example give a Product class with a property IsActive I could use an interface for the repository such as:

interface IProductRepository
{
    IEnumerable<Product> Load();
}

If a common task is to load active products then I would need to do:

IEnumerable<Product> activeProducts = repository.Load().Where(x => x.IsActive);

Where repository is a concrete implementation. If I used an abstract class such as:

abstract class ProductRepository
{
    protected abstract IEnumerable<Product> LoadCore();

    public IEnumerable<Product> Load()
    {
        return LoadCore().Where(x => x.IsActive);
    }
}

Then I could load active products using

IEnumerable<Product> activeProducts = repository.Load();

All the implementation for loading the product information is within the contrete class that derives ProductRepository so there is no coupling to the persistance layer. If it is found that there is another commonly performed activity then this could be added to the base class as a non-breaking change which could not be done using an interface.

Is there any benefit to using an interface instead of an abstract class? What potential drawbacks to using abstract classes could I come across?

I am using Castle Windsor as the IoC controller and .Net framework 3.5.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

暗地喜欢 2024-11-03 12:57:24

我不认为这个问题取决于 IoC;大多数这些框架并不关心您使用哪个。

在抽象基类上使用接口之间的一个大问题是 接口不能很好地进行版本控制

因此,抽象基类通常是更好的选择。我认为使用抽象基类没有任何缺点,除了获得诸如“为什么我不能创建这种类型的实例?”之类的支持问题之外。

I don't think this question hinges on IoC; most of these frameworks don't care which you use.

The big issue between using interfaces over abstract base classes is that interfaces cannot be versioned well.

Abstract base classes are usually the better choice because of this. I don't think there is any drawback to using an abstract base class, other than getting support questions like "why can't I create an instance of this type?"

眼泪也成诗 2024-11-03 12:57:24

该建议来自框架设计指南。 Microsoft 的此建议专门针对可重用类库而存在。换句话说:类似于 .NET 框架本身的框架。如果您正在创建业务线应用程序,则本指南不适用。它不适用,因为您不太可能在业务应用程序中遇到版本控制问题,因为您可以控制与您的类/接口通信的所有客户端代码。对于可重用库来说当然不是这种情况。

甚至文章Phil Haack,Will 引用的描述了这一点:

再次强调,这些指南是具体的
到框架开发(对于
静态类型语言),而不是
到其他类型的软件
发展。

因此,消除版本控制问题可能不是使用基类的好理由。然而,保持代码干燥是可以的。然而,使用基类和接口并不是相互排斥的;您可以让您的抽象类ProductRepository实现IProductRepository。但是,如果您这样做,则暴露 IProductRepository 以外的任何内容都不是一个好主意。

The recommendation comes from the Framework Design Guidelines. This recommendation of Microsoft exists specially for reusable class libraries. In other words: frameworks like the .NET framework itself. If you are creating a line of business application, this guideline does not apply. It does not apply because it is unlikely that you will have versioning problems in a line of business application, because you have control over all the client code that talks to your classes / interfaces. This is of course not the case for reusable libraries.

Even the article of Phil Haack, where Will references to describes this:

Again, these guidelines are specific
to Framework development (for
statically typed languages), and not
to other types of software
development.

Removing versioning problems is therefore probably not a good argument for using base classes. Keeping code DRY however could be. However, using base classes and interfaces aren't mutually exclusive; you can let your abstract class ProductRepository implement IProductRepository. If you do this however, exposing anything else than IProductRepository would be a bad idea.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文