首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AutoFac拦截,如何区分内部和外部

AutoFac拦截,如何区分内部和外部
EN

Stack Overflow用户
提问于 2016-06-23 01:37:49
回答 3查看 229关注 0票数 0

因此,我正在尝试实现拦截的概念,同时使用autofac。我没有做任何花哨的事情,比如实现动态拦截,我的每个类都有具体的代码。

我的代码(不是我真正的代码,这是我在网上找到的,但它说明了我的问题

代码语言:javascript
复制
public class DefaultProductService : IProductService
{       
    public Product GetProduct(int productId)
    {
        return new Product();
    }
}

public class CachedProductService : IProductService
{
    private readonly IProductService _innerProductService;
    private readonly ICacheStorage _cacheStorage;

    public CachedProductService(IProductService innerProductService, ICacheStorage cacheStorage)
    {
        if (innerProductService == null) throw new ArgumentNullException("ProductService");
        if (cacheStorage == null) throw new ArgumentNullException("CacheStorage");
        _cacheStorage = cacheStorage;
        _innerProductService = innerProductService;
    }

    public Product GetProduct(int productId)
    {
        string key = "Product|" + productId;
        Product p = _cacheStorage.Retrieve<Product>(key);
        if (p == null)
        {
            p = _innerProductService.GetProduct(productId);
            _cacheStorage.Store(key, p);
        }

        return p;
    }
}

public class ProductManager : IProductManager
{
    private readonly IProductService _productService;

    public ProductManager(IProductService productService)
    {
        _productService = productService;
    }
}

我的问题是,我希望我的ProductManager接收IProductService的" CachedProductService“,我希望我的CachedProductService接收IProductService的"DefaultProductService”。

我知道一些解决方案,但似乎没有一个是完全正确的。这样做的正确方法是什么?

谢谢!迈克尔

EN

回答 3

Stack Overflow用户

发布于 2016-06-23 02:01:40

您可以使用named dependencies来完成此操作。

不是说IProductService的实现是DefaultProductService,您将有两个通过它们的名称来区分的实现,如下所示:

代码语言:javascript
复制
builder.Register<DefaultProductService>().Named<IProductService>("DefaultProductService");
builder.Register<CachedProductService>().Named<IProductService>("CachedProductService");

文档中描述了几种不同的方法来指示您想要将哪个实现注入到给定的类中。这看起来像是最简单和最明确的:

代码语言:javascript
复制
public class ProductManager : IProductManager
{
    private readonly IProductService _productService;

    public ProductManager([WithKey("CachedProductService")]IProductService productService)
    {
        _productService = productService;
    }
}

老实说,我不喜欢它,因为它会导致类依赖于容器。它不允许您将其与类本身完全分开进行配置。使用Windsor,您可以在向容器注册依赖项时执行此操作,告诉容器使用哪个命名依赖项。

但这应该是可行的。

票数 1
EN

Stack Overflow用户

发布于 2016-06-23 15:12:04

您尝试做的似乎不是一个拦截概念,而是一个装饰器概念。

在面向对象的编程中,装饰器模式是一种设计模式,它允许静态或动态地将行为添加到单个对象,而不会影响同一类中其他对象的行为。来自

Autofac内置了对使用命名注册的装饰器的支持。

首先,您必须将基本组件和装饰器声明为命名注册:

代码语言:javascript
复制
builder.RegisterType<DefaultProductService>().Named<IProductService>("base"); 
builder.RegisterType<CacheProductServiceAdapter>().Named<IProductService>("cache"); 

然后你就可以注册你的装饰器了

代码语言:javascript
复制
builder.RegisterDecorator((c, inner) => c.ResolveNamed<IProductService>("cache", TypedParameter.From(inner)), fromKey : "base")
       .As<IProductService>(); 

您还可以有多个适配器:

代码语言:javascript
复制
builder.RegisterType<DefaultProductService>().Named<IProductService>("base"); 
builder.RegisterType<CacheProductServiceAdapter>().Named<IProductService>("cache"); 
builder.RegisterType<LoggingProductServiceAdapter>().Named<IProductService>("logging"); 

builder.RegisterDecorator((c, inner) => c.ResolveNamed<IProductService>("cache", TypedParameter.From(inner)), fromKey : "base", toKey:"cached"); 
builder.RegisterDecorator((c, inner) => c.ResolveNamed<IProductService>("logging", TypedParameter.From(inner)), fromKey : "cached")
       .As<IProductService>(); 

有关详细信息,请参阅adapters and decorators from Autofac documentation

票数 1
EN

Stack Overflow用户

发布于 2016-06-23 02:41:04

基于Scott的建议,我想我找到了一种方法,而不必在我的ProductManager类中引入对容器的依赖(我真的很讨厌这样做!)。我可以简单地实例化CachedProductService并告诉它使用哪个ProductService

代码语言:javascript
复制
builder.RegisterType(typeof(ProductService)).Named<IProductService>("DefaultProductService");
builder.Register(c => new CachedProductService(c.ResolveKeyed<IProductService>("DefaultProductService"))).As<IProductService>();
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37974821

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档