给出以下配置Autofac的方法:
public class DefaultConfigurationModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterApiControllers(System.Reflection.Assembly.GetExecutingAssembly());
}
}
并给出以下Web-Api控制器:
public class MyController : ApiController
{
private readonly int _someValue;
public MyController(int someValue)
{
_someValue = someValue;
}
}
将someValue
传递给MyController
的构造函数的最简单方法是什么?
我可以创建一个MyControllerConfig
类并使用AutoFac注册它:
public interface IMyControllerConfig
{
int SomeValue { get; }
}
public class MyControllerConfig : IMyControllerConfig
{
public int SomeValue { get; set; }
public MyControllerConfig(int someValue)
{
SomeValue = someValue;
}
}
并将其添加到我的configurationmodule:
builder.Register(c => new MyControllerConfig(123)).As<IMyControllerConfig>();
并更改MyApiController
以接受IMyControllerConfig
而不是int
:
public class MyController : ApiController
{
private readonly int _someValue;
public MyController(IMyControllerConfig myControllerConfig)
{
_someValue = myControllerConfig.SomeValue;
}
}
IMyControllerConfig
界面可能过度杀伤;我可以没有,只使用MyControllerConfig
。但是无论哪种方式;整个MyControllerConfig
类似乎有点过分将单个(原始)值传递给我的ApiController。 肯定会有一种更简单,更清洁,更整洁的方式吗?
如果这不是ApiController,我只会这样做:
builder.Register(c => new MyClass(123)).As<IMyInterface>();
...只是传入整数。但由于它是一个WebApi控制器,我想/喜欢使用RegisterApiControllers
方法(因为有很多控制器可以注册这个方法很好)我似乎把自己画成一个角落。并且更改MyController
以便RegisterApiControllers
方法无法获得'picked up'(例如,将其名称更改为不在'控制器'上结束)并手动注册此控制器'感觉 也有点'脏'。
另一种方法是实现一个依赖解析器并在那里做魔术,但同样,将一个原语传递给构造函数似乎需要做很多工作。我理解并同意,使用上述方法(使用MyControllerConfig
类)更适合未来的增强并传递更多的值而不会有太多的麻烦,但我不需要它用于这个特定的项目。项目中的所有其他API控制器都使用无参数构造函数或具有参数接口的构造函数。
请注意,上面示例中的123
“const”实际上来自配置文件,仅用于上述简洁;如果它是一个常量我不需要构造函数参数,可以直接将它放在MyController
类中。
答案 0 :(得分:0)
鉴于值是原始的,它来自配置,推荐的解决方案实际上是使用提供者类型的接口。有原始构造函数参数(string,int等)有很多问题,其中一个主要原因是它们是如此原始,你不能[从类型的角度]区分每个参数的目的实际上是。在容器中为一个需要连接字符串的类注册一个字符串,其他一些类可能会因为某些不相关的目的而无意中获取它。
您描述的示例are actually right out of our FAQ on this topic。如果你不能/不会使用lambda,更容易/更整洁/更清洁你正在寻找,那么提供者界面是下一个最好的选择。
请注意,如果要使用lambda,则无需更改控制器。
// Register everything nicely
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
// Override just the one controller
builder.Register(ctx => new MyController(123)).As<MyController>();
最后胜利,所以当Web API尝试解析MyController
时,它将从lambda获得注册。