gpt4 book ai didi

c# - 如何解决 Autofac 循环依赖?

转载 作者:行者123 更新时间:2023-12-01 09:29:09 24 4
gpt4 key购买 nike

最近开始使用 autofac,我遇到了一个循环依赖问题,我在使用 Unity 时已经克服了这个问题。这是我的代码:

 void Main()
{
var builder = new ContainerBuilder();

// 1) Every class needs logger
// 2) Logger needs AppSettingsProvider which needs AppEnvironmentProvider
// 3) Listener needs AppSettingsProvider which needs AppEnvironmentProvider

builder.RegisterType<Logger>().As<ILogger>().SingleInstance();
builder.RegisterType<AppSettingsProvider>().As<IAppSettingsProvider>().SingleInstance();
builder.RegisterType<AppEnvironmentProvider>().As<IAppEnvironmentProvider>().SingleInstance();

builder.RegisterType<Listener>().As<IListener>().SingleInstance();

var container = builder.Build();

var listener = container.Resolve<IListener>();
listener.Do();

}

public interface IListener
{
string Do();
}

public class Listener : IListener
{
IAppSettingsProvider appSettingsProvider;
public Listener(IAppSettingsProvider appSettingsProvider)
{
// this class needs IAppSettingsProvider to get some settings
// but not actually used on this example.
this.appSettingsProvider = appSettingsProvider;
}
public string Do()
{
return "doing something";
}
}

public interface ILogger
{
void Log(string message);
}

public class Logger : ILogger
{
IAppSettingsProvider appSettingsProvider;
public Logger(IAppSettingsProvider appSettingsProvider)
{
this.appSettingsProvider = appSettingsProvider;
}

public void Log(string message)
{
// simplified
if (this.appSettingsProvider.GetSettings())
{
Console.WriteLine(message);
}
}
}

public interface IAppSettingsProvider
{
// will return a class, here simplified to bool
bool GetSettings();
}

public class AppSettingsProvider : IAppSettingsProvider
{
ILogger logger;
public AppSettingsProvider(ILogger logger)
{
this.logger = logger;
}

public bool GetSettings()
{
this.logger.Log("Getting app settings");

return true;
}
}


public interface IAppEnvironmentProvider
{
string GetEnvironment();
}

public class AppEnvironmentProvider : IAppEnvironmentProvider
{
ILogger logger;
public AppEnvironmentProvider(ILogger logger)
{
this.logger = logger;
}
public string GetEnvironment()
{
this.logger.Log("returning current environment");

return "dev";
}
}

有关解决此问题的任何指示都会有所帮助。

最佳答案

您在这里有 2 个选项:

  • 使用属性注入(inject)
  • 使用工厂(可能会与您的工厂产生强烈的依赖关系)

  • 下面是一个使用属性注入(inject)的例子:
        static void Main()
    {
    var builder = new ContainerBuilder();

    // 1) Every class needs logger
    // 2) Logger needs AppSettingsProvider which needs AppEnvironmentProvider
    // 3) Listener needs AppSettingsProvider which needs AppEnvironmentProvider

    builder.RegisterType<Logger>().As<ILogger>().SingleInstance();

    builder.RegisterType<AppSettingsProvider>()
    .As<IAppSettingsProvider>()
    .SingleInstance()
    .PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies);

    builder.RegisterType<AppEnvironmentProvider>().As<IAppEnvironmentProvider>().SingleInstance();

    builder.RegisterType<Listener>().As<IListener>().SingleInstance();

    var container = builder.Build();

    var listener = container.Resolve<IListener>();

    Console.WriteLine(listener.Do());

    Console.Read();

    }

    public interface IListener
    {
    string Do();
    }

    public class Listener : IListener
    {
    IAppSettingsProvider appSettingsProvider;
    public Listener(IAppSettingsProvider appSettingsProvider)
    {
    // this class needs IAppSettingsProvider to get some settings
    // but not actually used on this example.
    this.appSettingsProvider = appSettingsProvider;
    }
    public string Do()
    {
    return "doing something using circular Dependency";
    }
    }

    public interface ILogger
    {
    void Log(string message);
    }

    public class Logger : ILogger
    {
    IAppSettingsProvider appSettingsProvider;
    public Logger(IAppSettingsProvider appSettingsProvider)
    {
    this.appSettingsProvider = appSettingsProvider;
    }

    public void Log(string message)
    {
    // simplified
    if (this.appSettingsProvider.GetSettings())
    {
    Console.WriteLine(message);
    }
    }
    }

    public interface IAppSettingsProvider
    {
    // will return a class, here simplified to bool
    bool GetSettings();
    }

    public class AppSettingsProvider : IAppSettingsProvider
    {
    ILogger logger;
    public AppSettingsProvider()
    {

    }

    public ILogger Logger { get; set; }

    public bool GetSettings()
    {
    Logger.Log("Getting app settings");

    return true;
    }
    }


    public interface IAppEnvironmentProvider
    {
    string GetEnvironment();
    }

    public class AppEnvironmentProvider : IAppEnvironmentProvider
    {
    ILogger logger;
    public AppEnvironmentProvider(ILogger logger)
    {
    this.logger = logger;
    }
    public string GetEnvironment()
    {
    this.logger.Log("returning current environment");

    return "dev";
    }
    }

    这是 Autofac 的建议:
    Autofac reference

    关于c# - 如何解决 Autofac 循环依赖?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43729119/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com