Autofac。使用委托工厂简化装饰器注册

时间:2018-03-22 09:44:25

标签: c# dependency-injection autofac

我希望通过使用委托工厂(autofac doc)来避免装饰器注册的更改。

我知道的当前方式每次更改装饰器构造函数依赖项时都会让我更改装饰器注册。例如,如果我向FooDecorator添加新的依赖项,有些IXyz,那么我必须通过添加c.Resolve<IXyz>()来更改装饰器注册。请查看CurrentWayToRegisterDecoratorDesiredWayToRegisterDecorator

[TestFixture]
internal sealed class AutofacRegistrationTests2 {


    interface IFoo {}

    interface IBar {}

    class Foo : IFoo {
    }

    class FooDecorator : IFoo {

        private IFoo _inner;
        private IBar _bar;

        public delegate IFoo Factory( IFoo inner );

        public FooDecorator( IFoo inner, IBar bar ) {
            _inner = inner;
            _bar = bar;
        }
    }

    [Test]
    public void CurrentWayToRegisterDecorator() {
        var builder = new ContainerBuilder();

        builder.RegisterType<Foo>()
            .Named<IFoo>( "baseImpl" );
        // Notice if I add a new dependency to FooDecorator constuctor then I need change this registration
        builder.RegisterDecorator<IFoo>(
            ( c, inner ) => new FooDecorator( inner, c.Resolve<IBar>() ), 
            fromKey: "baseImpl" );

        var container = builder.Build();

        Assert.That( container.Resolve<IFoo>(), Is.TypeOf<FooDecorator>() );
    }

    [Test]
    public void DesiredWayToRegisterDecorator() {
        var builder = new ContainerBuilder();

        builder.RegisterType<Foo>()
            .Named<IFoo>( "baseImpl" );
        builder.RegisterDecorator<IFoo>(
            // Test runner throw StackOverflowException here
            ( c, inner ) => c.Resolve<FooDecorator.Factory>().Invoke( inner ),
            fromKey: "baseImpl" );

        var container = builder.Build();

        Assert.That( container.Resolve<IFoo>(), Is.TypeOf<FooDecorator>() );
    }
}

0 个答案:

没有答案