ServiceLocator通过传递构造参数获取实例

use*_*405 5 c# asp.net unity-container service-locator

如何使用下面的构造函数使用服务定位器获取对象实例。ProductCode是用于初始化成员属性的构造函数参数。对于所有其他构造函数参数,我已在global.asax文件中使用 unity 注册了它们。

如果构造函数参数是引用类型,则获取对象实例的基本方法:

var productSettingsRepo = 
      ServiceLocator.Current.GetInstance<ProductSettingsRepository>();

public ProductSettingsRepository(ILogWriter logWriter, 
          ISecurityFunctionRepository securityRepo,
          IProductSettingsManager productSettingsManager,
          IReferenceDataService referenceDataService, 
          string productCode)
      {
          _logWriter = logWriter;
          _securityRepo = securityRepo;
          _productSettingsManager = productSettingsManager;
          _referenceDataService = referenceDataService;
          ProductInfo = GetProductData(productCode);
      }
Run Code Online (Sandbox Code Playgroud)

Yac*_*sad 4

服务定位器模式被认为是一种反模式,您可能需要重构以使用依赖注入

话虽如此,这是一种无需重构即可解决问题的方法:

创建一个工厂接口和类,该接口和类依赖于服务定位器来创建一个ProductSettingsRepository给定产品代码的类,如下所示:

public interface IProductSettingsRepositoryFactory
{
    ProductSettingsRepository Create(string productCode);
}

public class ProductSettingsRepositoryFactory : IProductSettingsRepositoryFactory
{
    public ProductSettingsRepository Create(string productCode)
    {
        return new ProductSettingsRepository(
            ServiceLocator.Current.GetInstance<ILogWriter>(),
            ServiceLocator.Current.GetInstance<ISecurityFunctionRepository>(),
            ServiceLocator.Current.GetInstance<IProductSettingsManager>(),
            ServiceLocator.Current.GetInstance<IReferenceDataService>(),
            productCode);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后确保您向 Unity 容器注册该工厂,如下所示:

unity_container
   .RegisterType<IProductSettingsRepositoryFactory, ProductSettingsRepositoryFactory>();
Run Code Online (Sandbox Code Playgroud)

然后,您可以像这样使用它:

var factory = ServiceLocator
                   .Current
                   .GetInstance<IProductSettingsRepositoryFactory>();

var productSettingsRepo = factory.Create("my product code");
Run Code Online (Sandbox Code Playgroud)

  • 服务定位器模式有合适的地方。您链接的示例是服务定位器模式不合适的一个很好的例子。但这并不意味着它是普遍的反模式。几乎所有好的模式都有可能应用于不合适的场景。成为一名优秀的架构师的一部分是了解模式的适当应用。+1 表示搁置您的意见并帮助解决问题。 (2认同)