如何注册手动创建的装饰器实例
How to register manually-created decorator instance
通常,要使用构造函数注入注册一些配置值,我会这样做:
string setting = ConfigurationManager.AppSettings["SomeSetting"];
container.Register<IService>(new Service(setting));
你如何完成类似的事情,以便将配置值传递给装饰器构造函数?
是创建一些可以注入装饰器的配置提供程序 class 的唯一方法吗?似乎 RegisterDecorator 应该有一个重载,允许根据需要手动更新 class。
有几种方法可以实现这一点。如果对象图的那部分很简单,手动构建对象图可能会得到最好的结果:
container.RegisterSingleton<IService>(new ServiceDecorator(
setting,
new RealService()));
// or
container.Register<IService>(() => new ServiceDecorator(
setting,
new RealService()));
在 Simple Injector 中没有 RegisterDecorator
的委托重载,这意味着您不能使用手动连接的 RegisterDecorator
注册装饰器,但是有一些替代方法。
您可以将设置值提取到它自己的 class。这允许将抽象注入到装饰器中:
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));
如果装饰器本身无法更改,您可以从中派生 class:
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,但这有点复杂,我通常只在集成场景中建议这样做。
通常,要使用构造函数注入注册一些配置值,我会这样做:
string setting = ConfigurationManager.AppSettings["SomeSetting"];
container.Register<IService>(new Service(setting));
你如何完成类似的事情,以便将配置值传递给装饰器构造函数?
是创建一些可以注入装饰器的配置提供程序 class 的唯一方法吗?似乎 RegisterDecorator 应该有一个重载,允许根据需要手动更新 class。
有几种方法可以实现这一点。如果对象图的那部分很简单,手动构建对象图可能会得到最好的结果:
container.RegisterSingleton<IService>(new ServiceDecorator(
setting,
new RealService()));
// or
container.Register<IService>(() => new ServiceDecorator(
setting,
new RealService()));
在 Simple Injector 中没有 RegisterDecorator
的委托重载,这意味着您不能使用手动连接的 RegisterDecorator
注册装饰器,但是有一些替代方法。
您可以将设置值提取到它自己的 class。这允许将抽象注入到装饰器中:
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));
如果装饰器本身无法更改,您可以从中派生 class:
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,但这有点复杂,我通常只在集成场景中建议这样做。