2010-04-29 47 views
5

我正在构建一个使用AutoFac 2的DI应用程序。我一直在reading,应该避免使用静态IoCHelper(服务定位器)。使用AutoFac避免服务定位器2

IoCHelper.cs

public static class IoCHelper 
{ 
    private static AutofacDependencyResolver _resolver; 

    public static void InitializeWith(AutofacDependencyResolver resolver) 
    { 
     _resolver = resolver; 
    } 

    public static T Resolve<T>() 
    { 
     return _resolver.Resolve<T>(); 
    } 
} 

从回答一个previous question,我找到了一种方法,以帮助减少通过使用Auto-generated Factories使用我IoCHelper在我的UnitOfWork的需要。沿着这条道路继续前进,我很好奇,如果我能完全消除我的IoCHelper。

下面是这种情况:

我有作为围绕我的配置实现包装的静态设置类。由于Settings类是大多数其他类的依赖项,所以包装器使我无需在整个应用程序中注入设置类。

Settings.cs

public static class Settings 
{ 
    public static IAppSettings AppSettings 
    { 
     get 
     { 
      return IoCHelper.Resolve<IAppSettings>(); 
     } 
    } 
} 

public interface IAppSettings 
{ 
    string Setting1 { get; } 
    string Setting2 { get; } 
} 

public class AppSettings : IAppSettings 
{ 
    public string Setting1 
    { 
     get 
     { 
      return GetSettings().AppSettings["setting1"]; 
     } 
    } 

    public string Setting2 
    { 
     get 
     { 
      return GetSettings().AppSettings["setting2"]; 
     } 
    } 

    protected static IConfigurationSettings GetSettings() 
    { 
     return IoCHelper.Resolve<IConfigurationSettings>(); 
    } 
} 

有没有办法来处理这不使用服务定位器,而不必诉诸于注射的AppSettings到每一个班级?下面列出的是3个区域中,我一直倚在服务定位,而不是构造器注入:

  • 的AppSettings
  • 记录
  • 缓存

回答

4

我宁愿注入IAppSettings到每个需要它的类只是为了让他们从Settings的隐藏依赖中清除干净。问题是,你是否真的需要把这种依赖性传递给每一个班级?

如果你真的想用一个静态的Settings类,我至少会尝试使其测试友好/伪造。试想一下:

public static class Settings 
{ 
    public static Func<IAppSettings> AppSettings { get; set; } 
} 

你在哪里建立你的容器:

var builder = new ContainerBuilder(); 
... 
var container = builder.Build(); 

Settings.AppSettings =() => container.Resolve<IAppSettings>(); 

这将允许测试期间假货换出:现在

Settings.AppSettings =() => new Mock<IAppSettings>().Object; 

AppSettings类(我假设只有一个)你可以用普通的构造函数注入来完成。我还假设你真的想在每次调用设置属性时都做一个解决方案,这样就可以注入一个工厂委托来在需要时检索一个实例。如果不需要,您应该直接注入IConfigurationSettings服务。

public class AppSettings : IAppSettings 
{ 
    private readonly Func<IConfigurationSettings> _configurationSettings; 

    public AppSettings(Func<IConfigurationSettings> configurationSettings) 
    { 
     _configurationSettings = configurationSettings; 
    } 

    public string Setting1 
    { 
     get 
     { 
      return _configurationSettings().AppSettings["setting1"]; 
     } 
    } 

    public string Setting2 
    { 
     get 
     { 
      return _configurationSettings().AppSettings["setting2"]; 
     } 
    } 
} 
+0

这是一个很好的观点。实际上,我可能不需要将这些依赖项注入到EVERY类中,但是对于我将相同的依赖项注入大量类的情况,我只是很好奇,是否有一些DI最佳实践。 – 2010-04-29 14:58:20

+1

查看我更新的答案。真相被告知,我曾经被迫做过这样的事情:当构造函数注入不能被使用时(设计者需要一个无参数的构造函数)。 – 2010-04-29 20:20:56

+0

很好的解决方法 – Baldy 2011-06-20 14:51:01