【问题标题】:Property Injection with Autofac isn't working使用 Autofac 进行属性注入不起作用
【发布时间】:2017-06-24 00:10:28
【问题描述】:

我一直在查看 Autofac 的示例和文档,但无法使其正常工作。

我们有一个辅助类Core.Helpers.Tokens,其属性设置如下:

namespace Core.Helpers
{
    public static class Tokens
    {
        private static IConfigurationManager ConfigurationManager;

        public static string GetToken()
        {
            var sessionTokenName = ConfigurationManager.GetAppSetting("SessionTokenName");
            return (string) HttpContext.Current.Session[sessionTokenName];
        }
    }
}

配置是这样设计的:

namespace Core.Config
{
    public interface IConfigurationManager
    {
        //...
    }

    public class WebConfigConfigurationManager : IConfigurationManager
    {
        //...
    }
}

在我们的 MVC Web 应用程序中(它引用并使用 Core.HelpersStartup.cs 我正在尝试注册 IConfigurationManager 以进行属性注入。

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var builder = new ContainerBuilder();

        // REGISTER CONTROLLERS SO DEPENDENCIES ARE CONSTRUCTOR INJECTED
        builder.RegisterControllers(typeof(MvcApplication).Assembly);
        builder.RegisterModule<AutofacWebTypesModule>();
        builder.RegisterFilterProvider();
        builder.RegisterType<WebConfigConfigurationManager>().As<IConfigurationManager>().PropertiesAutowired();

        RegisterTypes(builder);

        // BUILD THE CONTAINER
        var container = builder.Build();
        var webConfig = container.Resolve<IConfigurationManager>();

        // REPLACE THE MVC DEPENDENCY RESOLVER WITH AUTOFAC
        DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

        // REGISTER WITH OWIN
        app.UseAutofacMiddleware(container);
        app.UseAutofacMvc();
    }

网页代码调用GetToken时,ConfigurationManager为空。我错过了什么?

【问题讨论】:

    标签: c# dependency-injection autofac


    【解决方案1】:

    一个错误是您的Tokens.ConfigurationManager 是一个私有字段,而属性注入适用于公共属性

    此外,它必须是实例属性,而不是静态属性。所以最后应该是

    public IConfigurationManager ConfigurationManager{get;set;}
    

    但这意味着你还必须注入一个 Tokens 实例,这将不再是一个静态帮助类,你必须重新设计,有一些选择:

    1. 如果您在希望从中调用 GetTokens 的任何地方都有一个 IConfigurationManager 实例,则可以将其作为输入参数传递给 GetTokens()
    2. 您将此静态帮助程序提升为依赖项(例如 ITokenService ? ),该依赖项将被注入到需要它的任何地方。而不是让它成为静态的, 您可以使用 Autofac 生命周期管理使其成为单例。 (可能是最好的解决方案)
    3. 最糟糕的解决方案,但最小的改变,一个不必放弃这是一个静态帮助类的工作,是使属性使用 DependencyResolver 而不是注入,例如:

      私有静态 IConfigurationManager ConfigurationManager{ get { return DependencyResolver.Current.GetService();} }

    【讨论】:

    • 好的,我知道它需要公开。但是你不能在静态类中声明实例成员。
    • 为什么第三个是最差的?
    • 第三种解决方案本质上是放弃DI,降级使用Service Locator,它有很多缺点,甚至有人认为它是一种反模式。 stackoverflow.com/questions/1557781/…
    【解决方案2】:

    你正在解析 IConfigurationManager,你应该正在解析 WebConfigurationManager。

    如果您有 5 个使用 IConfigurationmanager 的类,则解析接口不会告诉 autoface 您要使用哪个具体类,哪个具有此接口。

    【讨论】:

    • 当我尝试解析 var webConfig = container.Resolve&lt;WebConfigConfigurationManager&gt;(); 时,我得到:Autofac.dll 中出现“Autofac.Core.Registration.ComponentNotRegisteredException”类型的异常,但未在用户代码中处理附加信息:请求的服务'Clark.Chains.Core.Config.WebConfigConfigurationManager' 尚未注册。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-26
    相关资源
    最近更新 更多