如何在Autofac中混合装饰器? [英] How to mix decorators in autofac?

查看:147
本文介绍了如何在Autofac中混合装饰器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够与Autofac搭配使用装饰器.

I'd like to be able to mix and match decorators with Autofac.

例如,假设我有一个由Repository类实现的IRepository接口.
我可能有以下装饰器:RepositoryLocalCache,RepositoryDistributedCache,RepositorySecurity,RepositoryLogging ...,您会得到一些想法.

For example, let's say I have an IRepository interface, implemented by the Repository class.
I could have the following decorators: RepositoryLocalCache, RepositoryDistributedCache, RepositorySecurity, RepositoryLogging..., you get the ideea.

基于配置设置,我想用所需的装饰器装饰基本实现.可以是一个,也可以是多个装饰器.

Based on config settings, I'd like to decorate the basic implementation with the needed decorators. That can be none, one or multiple decorators.

我熟悉注册一个装饰器或以固定顺序连接一个装饰器的语法,但是如何使它动态化呢?

I am familiar with the syntax of registering one decorator, or a chain of them in a fixed order, but how can I make this dynamic?

推荐答案

正如史蒂文(Steven)指出的那样,Autofac中的RegisterDecorator方法并不是真正为这种情况设计的,并且使用起来很笨拙.它们是为某些情况而构建的,这些情况很难使用常规的Autofac注册来实现-这样做的本机"方法更加简洁.

As Steven points out above, the RegisterDecorator methods in Autofac aren't really designed for this scenario, and are pretty clunky to use. They were built for some situations that were hard to implement using regular Autofac registrations - the "native" way of doing this is much cleaner.

例如,IFoo是服务,而Impl是具体的(例如存储库)实现.

For the example, IFoo is the service and Impl is the concrete (e.g. repository) implementation.

interface IFoo { }

class Impl : IFoo { }

class DecoratorA : IFoo
{
    public DecoratorA(IFoo decorated) { }
}

class DecoratorB : IFoo
{
    public DecoratorB(IFoo decorated) { }
}

首先使用其具体类型注册所有组件:

First register all components using their concrete types:

var builder = new ContainerBuilder();

builder.RegisterType<Impl>();
builder.RegisterType<DecoratorA>();
builder.RegisterType<DecoratorB>();

Lambda注册也可以,只需确保它们不要使用As<IFoo>().

Lambda registrations are fine too, just make sure they don't use As<IFoo>().

现在使用包装器将它们链接起来,以提供完全配置的服务:

Now a wrapper that chains them up to provide the fully-configured service:

bool useA = true, useB = false;

builder.Register(c =>
{
    IFoo result = c.Resolve<Impl>();

    if (useA)
        result = c.Resolve<DecoratorA>(TypedParameter.From(result));

    if (useB)
        result = c.Resolve<DecoratorB>(TypedParameter.From(result));

    return result;
}).As<IFoo>();

useAuseB是您从配置中动态提供的值.

useA and useB are your dynamically provided values from configuration.

现在解析(或依赖)IFoo将为您提供动态构建的装饰器链.

Now resolving (or taking a dependency on) IFoo will get you a dynamically-constructed decorator chain.

using (var container = builder.Build())
{
    var foo = container.Resolve<IFoo>();

如果您使用的是泛型,那么事情会比较棘手,因为您没有提到泛型,所以我不会讨论,但是如果您使用泛型,请提出另一个问题.

If you're using generics things are trickier, since you don't mention them I'll not go into it but if you are then please post another question.

这篇关于如何在Autofac中混合装饰器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆