我有2个控制器,都需要一个MySettings代表一组设置的对象.每个控制器都需要其自定义设置集.为了在模块注册时执行此操作,我手动创建了2个设置对象并将它们都放入容器中.问题是如何指定每个控制器应该注入自己的预定义的MySettings类型的自定义初始化实例?
更新:
现在有一个丑陋的解决方法,基本上使Autofac无用,因为所有解析都是手工完成的:
public class MyModule : Module {
protected override void Load(ContainerBuilder builder) {
builder.Register(context => {
var productControllerSettings = new MyListSettings(
pageSize: 20,
orderBy: "Name",
orderDirection: OrderDirection.Ascending
);
// and hell of other parameters that I need to resove
// by hands by doing context.Resolve<...> for each of them
var productController = new ProductController(
productControllerSettings
/*, the reset of parameters */
);
return productController;
});
builder.Register(context => {
var userControllerSettings = new MyListSettings {
pageSize: 20,
orderBy: "LastName",
orderDirection: OrderDirection.Ascending
};
var userController = new UserController(
userControllerSettings
/*, the rest of parameters resolved by calling context.Resolve<> by hands */
);
return userController;
});
}
}
Run Code Online (Sandbox Code Playgroud)
我希望一定有更好的方法.
UPDATE2:
解决这一不足的另一种方法是根据MySettings类创建2个新类设置.这样每个实例唯一对应一个类,Autofac可以轻松解决它.我不想仅仅为了使Autofac工作.
最简单的解决方案是使用Autofac 的Named注册功能.
因此MyControllerSettings,请使用名称注册实例,并在注册控制器时将此名称用作参数:
var productControllerSettings = new MyListSettings(
pageSize: 20,
orderBy: "Name",
orderDirection: OrderDirection.Ascending);
builder.RegisterInstance(productControllerSettings)
.Named<MyListSettings>("productControllerSettings");
var userControllerSettings = new MyListSettings(
pageSize: 20,
orderBy: "LastName",
orderDirection: OrderDirection.Ascending);
builder.RegisterInstance(userControllerSettings)
.Named<MyListSettings>("userControllerSettings");
builder.RegisterType<ProductController>()
.WithParameter(
ResolvedParameter.ForNamed<MyListSettings>("productControllerSettings"));
builder.RegisterType<UserController>()
.WithParameter(
ResolvedParameter.ForNamed<MyListSettings>("userControllerSettings"));
Run Code Online (Sandbox Code Playgroud)
但是,此解决方案需要在注册期间列出所有控制器命名的参数对,这可能容易出错.
另一种方法是,您不直接依赖于MyListSettings控制器,而是依赖于"MyListSettings"提供程序.你可以有这样的供应商作为一个具体的类,或者您可以使用Autofac的内置关联种类为这个喜欢IIndex创造一个轻量级的供应商.
所以你的控制器看起来像这样:
public class ProductController
{
private readonly MyListSettings productControllerSettings;
public ProductController(Func<Type, MyListSettings> settingsProvider)
{
this.productControllerSettings = settingsProvider(GetType());
}
}
public class UserController
{
private readonly MyListSettings userControllerSettings;
public UserController(Func<Type, MyListSettings> settingsProvider)
{
this.userControllerSettings = settingsProvider(GetType());
}
}
Run Code Online (Sandbox Code Playgroud)
并相应注册:
var productControllerSettings = new MyListSettings(
pageSize: 25,
orderBy: "Name",
orderDirection: OrderDirection.Ascending);
builder.RegisterInstance(productControllerSettings)
.Keyed<MyListSettings>(typeof (UserController1));
var userControllerSettings = new MyListSettings(
pageSize: 20,
orderBy: "LastName",
orderDirection: OrderDirection.Ascending);
builder.RegisterInstance(userControllerSettings)
.Keyed<MyListSettings>(typeof (ProductController1));
//register the provider func
builder.Register<Func<Type, MyListSettings>>(
c => (t) => c.Resolve<IIndex<Type, MyListSettings>>()[t]);
builder.RegisterType<ProductController>();
builder.RegisterType<UserController>();
Run Code Online (Sandbox Code Playgroud)
你应该注意,你可以使用任何东西,Keyed而不仅仅是Type你可以识别哪个控制器应该获得哪些设置,如字符串,枚举等.
| 归档时间: |
|
| 查看次数: |
2329 次 |
| 最近记录: |