通常,要使用构造函数注入注册一些配置值,我会这样做:
string setting = ConfigurationManager.AppSettings["SomeSetting"];
container.Register<IService>(new Service(setting));
为了将配置值传递给装饰器构造函数,你如何完成类似的工作?
创建一些可以注入装饰器的配置提供程序类的唯一方法是什么?似乎RegisterDecorator应该有一个重载,允许根据需要手动新建类。
答案 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,但这有点复杂,我通常只在集成场景中提出建议。