ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c# – 注册工厂方法不会阻止Autofac调用ctor

2019-07-05 12:14:38  阅读:396  来源: 互联网

标签:c dependency-injection autofac factory-method


我有一个名为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;
}

我希望Autofac在我要求解析ServiceConfiguration时调用LoadConfiguration.但它似乎试图在ServiceConfiguration上调用ctor.例如.叫这行:

var c = container.Resolve<ServiceConfiguration>();

导致此错误:

Autofac.Core.DependencyResolutionException: ‘An error occurred during
the activation of a particular registration. See the inner exception
for details. Registration: Activator = ServiceConfiguration
(ReflectionActivator), Services = [ServiceConfiguration], Lifetime =
Autofac.Core.Lifetime.CurrentScopeLifetime, Sharing = Shared,
Ownership = OwnedByLifetimeScope’

而InnerException是:

DependencyResolutionException: None of the constructors found with
‘Autofac.Core.Activators.Reflection.DefaultConstructorFinder’ on type
‘ServiceConfiguration’ can be invoked with the available services and
parameters:
Cannot resolve parameter ‘JobsConfiguration jobs’ of constructor ‘Void .ctor(JobsConfiguration)’.

你能找到我错过的东西吗?

更新:
我没有错过JobsConfiguration的注册.实际上它不是可注册类型,我不想注册它.我根本不想调用ctor(服务是从json文件构建的),而是每当有人要求ServiceConfiguration时我都希望Autofac调用LoadConfiguration()并使用它的返回值.

UPDATE2:

过了一会儿,似乎从ServiceConfiguration中提取了一个接口 – 比如IServiceConfiguration – 并且注册/解析接口工作得很好.但我无法弄清楚为什么!我是说这个:

builder.Register(c=>LoadConfiguration())
       .As<IServiceConfiguration>();

var c = container.Resolve<IServiceConfiguration>();

作品.但具体版本没有.所以为什么?有什么不同?

解决方法:

您应该努力将配置文件的加载与对象组合分开.这意味着在调用Resolve时最好不要加载配置.改变这一点是微不足道的:

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.

标签:c,dependency-injection,autofac,factory-method
来源: https://codeday.me/bug/20190705/1387334.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有