Ami*_*mit 4 c# circular-dependency autofac
最近开始使用 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";
}
}
Run Code Online (Sandbox Code Playgroud)
任何有关解决此问题的指示都会有所帮助。
小智 5
您在这里有 2 个选择:
这是使用属性注入的示例:
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";
}
}
Run Code Online (Sandbox Code Playgroud)
这是 Autofac 建议: Autofac 参考
Lazy<ILogger>另一种解决方法是在依赖服务的构造函数中使用。
public class AppSettingsProvider : IAppSettingsProvider
{
Lazy<ILogger> logger;
public AppSettingsProvider(Lazy<ILogger> logger)
{
this.logger = logger;
}
public bool GetSettings()
{
this.logger.Value.Log("Getting app settings");
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7289 次 |
| 最近记录: |