我遇到Autofac问题,似乎EnableClassInterceptors干扰了我使用.WithParameter(...)的能力。使用下面的代码在Service上调用构造函数时,不会填充someString。注意:
我的注册码片段如下所示:
var builder = new ContainerBuilder();
builder.RegisterType<Dependency>.As<IDependency>.InstancePerLifetimeScope();
builder.RegisterType<Service>()
.As<IService>()
.WithParameter(new NamedParameter("someString", "TEST"))
.EnableClassInterceptors()
.InterceptedBy(typeof(LogExceptionsInterceptor));
Service的构造函数看起来像这样:
public class Service : IService
{
public Service(IDependency dependency, string someString)
{
if(dependency == null)
throw ArgumentNullException(nameof(dependency));
if(someString == null)
//**throws here**
throw ArgumentNullException(nameof(someString));
}
}
[猜猜] 我想到的是,当调用EnableClassInterceptors时,会生成一个代理类,其构造函数在现有的构造函数之上,但参数名称不要复制到代理类/构造函数中。
这是一个问题吗?有没有办法形成允许同时使用WithParameter和EnableClassInterceptors的注册?这是Autofac中的错误吗?
答案 0 :(得分:2)
您的猜测是正确的:生成的代理类不保留构造函数参数名称。
目前没有办法在DynamicProxy中影响它,所以这不是Autofac的错误(尽管Autofac文档网站上没有记录此边缘情况)。
这是您的原始Service
课程参数的样子:
typeof(Service).GetConstructors()[0].GetParameters()
{System.Reflection.ParameterInfo[2]}
[0]: {ConsoleApplication10.IDependency dependency}
[1]: {System.String someString}
但生成的代理不保留名称:
GetType().GetConstructors()[0].GetParameters()
{System.Reflection.ParameterInfo[3]}
[0]: {Castle.DynamicProxy.IInterceptor[] }
[1]: {ConsoleApplication10.IDependency }
[2]: {System.String }
因此,您有两个不太强大的选项可以使用WithParameter
来解决此限制:
使用TypedParamter
和string
作为类型:
.WithParameter(new TypedParameter(typeof(string), "TEST"))
但是,如果你有多个相同类型的参数,那么它将无法运作
在这种情况下使用PositionalParameter
如果代理类型需要添加1
.WithParameter(new PositionalParameter(2, "TEST"))
另一个选择是不使用原始字符串类型,但创建一个包装器,例如MyServiceParameter
或创建另一项服务,可以为您的其他服务提供这些string
配置值。