Simple Injector - 如何注册手动创建的装饰器实例

时间:2015-12-15 05:25:32

标签: configuration decorator simple-injector

通常,要使用构造函数注入注册一些配置值,我会这样做:

string setting = ConfigurationManager.AppSettings["SomeSetting"];
container.Register<IService>(new Service(setting));

为了将配置值传递给装饰器构造函数,你如何完成类似的工作?

创建一些可以注入装饰器的配置提供程序类的唯一方法是什么?似乎RegisterDecorator应该有一个重载,允许根据需要手动新建类。

1 个答案:

答案 0 :(得分:4)

有几种方法可以实现这一目标。如果对象图的那部分很简单,手动构建对象图可能会得到最好的结果:

container.RegisterSingleton<IService>(new ServiceDecorator(
    setting,
    new RealService()));

// or 
container.Register<IService>(() => new ServiceDecorator(
    setting,
    new RealService()));

Simple Injector中RegisterDecorator没有委托重载,这意味着您无法使用手动连接的RegisterDecorator注册装饰器,但有一些替代方法。

您可以将设置值提取到自己的类中。这允许将抽象注入装饰器:

container.RegisterSingleton<MySetting>(new MySetting(setting));
container.RegisterDecorator(typeof(IService), typeof(ServiceDecorator));

public ServiceDecorator : IService {
    public ServiceDecorator(MySetting setting, IService decoratee) { }
}

或者您可以将设置注入装饰器的属性:

container.RegisterDecorator(typeof(IService), typeof(ServiceDecorator));
container.RegisterInitializer<ServiceDecorator>(dec => dec.Setting = setting);

public ServiceDecorator : IService {
    public string Setting { get; set; }
    public ServiceDecorator(IService decoratee) { }
}

或者您可以将Setting设为静态属性:

ServiceDecorator.Setting = setting;
container.RegisterDecorator(typeof(IService), typeof(ServiceDecorator));

如果装饰器本身无法更改,您可以从该类派生:

public ServiceDecoratorWithSetting : ServiceDecorator {
    public static string Setting { get; set; }
    public ServiceDecorator(IService decoratee) : base(Setting, decoratee) { }
}

ServiceDecoratorWithSetting.Setting = setting;
container.RegisterDecorator(typeof(IService), typeof(ServiceDecoratorWithSetting));

最后一个选项是override parameter injection behavior,但这有点复杂,我通常只在集成场景中提出建议。