我有一个名为ServiceConfiguration
的服务,其中有一个非默认的ctor。我正在尝试使用工厂方法通过Autofac注册它:
builder.Register(c=>LoadConfiguration())
.As<ServiceConfiguration>();
这是简单的LoadConfiguration
方法:
private ServiceConfiguration LoadConfiguration() {
const string fileName = "app.json";
var json = File.ReadAllText(fileName, Encoding.UTF8);
var model = JsonConvert.DeserializeObject<ServiceConfiguration>(json);
return model;
}
我希望当我要求解析LoadConfiguration
时,Autofac会呼叫ServiceConfiguration
。但似乎正在尝试在ctor
上调用ServiceConfiguration
。例如。呼叫此行:
var c = container.Resolve<ServiceConfiguration>();
导致此错误:
Autofac.Core.DependencyResolutionException:'在执行过程中发生错误 激活特定注册。看到内部异常 有关详细信息。注册:Activator = ServiceConfiguration (ReflectionActivator),服务= [ServiceConfiguration],生命周期= Autofac.Core.Lifetime.CurrentScopeLifetime,共享=共享, 所有权= OwnedByLifetimeScope'
而InnerException是:
DependencyResolutionException:找不到与 类型上的“ Autofac.Core.Activators.Reflection.DefaultConstructorFinder” 可以使用可用服务来调用“ ServiceConfiguration”,并且 参数: 无法解析构造函数“ Void .ctor(JobsConfiguration)”的参数“ JobsConfiguration作业”。
你能找出我想念的东西吗?
更新:
我没有错过JobsConfiguration
的注册。实际上,这不是可注册的类型,我不想注册它。我根本不希望ctor
被调用(该服务是从json文件构建的),而是每当有人要求ServiceConfiguration
时我都希望Autofac呼叫LoadConfiguration()
并使用它返回值。
UPDATE2:
过一会儿,似乎从ServiceConfiguration
中提取了一个接口-说IServiceConfiguration
-然后注册/解析该接口就可以了。但是我不知道为什么!我的意思是:
builder.Register(c=>LoadConfiguration())
.As<IServiceConfiguration>();
var c = container.Resolve<IServiceConfiguration>();
有效。但具体版本不行。所以为什么?有什么不同?
答案 0 :(得分:1)
您应努力将配置文件的加载与对象组合分开。这意味着在调用Resolve
时最好 not 加载配置。更改此设置很简单:
ServiceConfiguration configuration = LoadConfiguration();
builder.RegisterInstance(configuration);
也就是说,您指定的注册应该有效:
builder.Register(c => LoadConfiguration())
.As<ServiceConfiguration>();
与以下相同:
builder.Register(c => LoadConfiguration());
通过此注册,Autofac将不自动连接ServiceConfiguration
构造函数,但将其留给提供的委托。可能发生了某种情况,您的帖子没有显示。
我使用了以下MCVE(使用Autofav 4.8.1)来验证它是否有效:
class ServiceConfiguration
{
public ServiceConfiguration(int a, double b) => Console.WriteLine("ctor called.");
}
static ServiceConfiguration LoadConfiguration() => new ServiceConfiguration(2, 6);
static void Main(string[] args)
{
var builder = new ContainerBuilder();
builder.Register(_ => LoadConfiguration()).As<ServiceConfiguration>();
builder.Build().Resolve<ServiceConfiguration>();
}
最后注意:确保ServiceConfiguration
不是注入到许多使用者中的应用程序范围的配置类。要了解应用程序范围的配置类有什么问题,请阅读this Q/A。