特定场景下依赖注入构造函数参数解析问题
解决Autofac中动态传递依赖类名称给MyService的问题
根据你的场景,你需要让MyService在初始化时自动获取依赖它的类(比如A)的名称,这里提供几个可行的方案,基于Autofac的特性来实现:
方案1:在依赖类的注册中显式传递参数
这是最直接的方式,当注册A时,显式为它依赖的MyService构造函数传入A的类名:
builder.RegisterType<A>() .WithParameter( (parameterInfo, context) => parameterInfo.ParameterType == typeof(MyService), (parameterInfo, context) => new MyService(typeof(A).Name) );
优点:逻辑简单,容易理解和维护;
缺点:如果有多个类依赖MyService,每个类都需要单独注册并传递参数,重复代码较多。
方案2:使用工厂模式让依赖类主动传递自身类型
修改A的构造函数,让它接收一个工厂委托,在构造时主动传入自身类型,这样MyService的注册可以通用:
首先调整A的代码:
public class A { public A(Func<Type, MyService> myServiceFactory) { var myService = myServiceFactory(typeof(A)); // 在这里使用myService } }
然后在Autofac容器中注册这个工厂委托:
builder.Register<Func<Type, MyService>>(context => { var componentContext = context.Resolve<IComponentContext>(); return targetType => new MyService(targetType.Name); }); // 正常注册MyService(如果工厂里直接实例化,甚至可以不用单独注册) builder.RegisterType<MyService>().AsSelf();
优点:灵活性高,所有依赖MyService的类只需要通过工厂传递自身类型即可,无需重复配置注册;
缺点:需要修改依赖类的构造函数,引入工厂委托。
方案3:利用Autofac的解析上下文自动获取依赖类型
如果你希望完全在MyService的注册中自动处理,可以借助Autofac的IResolveOperation来获取当前正在解析的服务类型(即依赖MyService的类):
builder.RegisterType<MyService>() .AsSelf() .WithParameter( (parameterInfo, context) => parameterInfo.ParameterType == typeof(string) && parameterInfo.Name == "className", (parameterInfo, context) => { // 获取当前的解析操作上下文 var resolveOperation = context.Resolve<IResolveOperation>(); // 栈顶的请求就是当前正在解析的服务(比如A) var currentRequest = resolveOperation.CurrentRequest; return currentRequest.ServiceType.Name; });
注意:这个方案依赖Autofac的内部服务IResolveOperation,虽然当前版本可用,但未来版本可能有变动;另外,如果MyService被注册为单例,这个方法会失效——因为单例只会初始化一次,类名将固定为第一个解析它的类的名称,所以仅适合瞬态或作用域的MyService。
优点:无需修改业务类代码,自动获取依赖类名称;
缺点:依赖Autofac内部API,单例场景不适用。
内容的提问来源于stack exchange,提问作者Anton
相关产品推荐
相关产品推荐

