初始化接口的正确方法是什么?



Mine不是一个WEB应用程序。这完全是 C# 库。我的界面非常简单,在一个单独的 C# 库中:

public interface IDataRepository
{
Task<string> GetAppSettingAsync(string name);
}

我正在另一个 C# 库中访问此 DLL。

public class BaseConsumer
{
public IDataRepository DataRepository => new DataRepository();
public async Task<string> AppSetting()
{
return await DataRepository.GetAppSettingAsync("name");
}
}

在 web/windows 应用程序中,我们通过构造函数进行依赖注入和注入存储库/服务。在这里我没有这个选择,因为我的库有无参数构造函数。

如何获取IDataRepository而不是使用新DataRepository初始化它?

在处理不符合依赖关系注入的遗留代码时,要考虑的选项是如上所述的服务定位器模式。我采用的变体我称之为懒惰属性注入:

使用 Autofac,我将容器包装在单例中以便于访问。

然后在需要依赖项的服务类中:

private IDataRepository _dataRepository = null;    
public IDataRepository DataRepository 
{
get { return _dataRepository ?? (_dataRepository = ContainerRegistry.Instance.Resolve<IDataRepository>());}
set { _dataRepository = value; }
}

此方法的好处是,仅在需要时解析依赖项,并且仅在第一次需要时才解析依赖项。这也是一项非常简单的验证检查,可确保服务定位器不会在不应该使用的任何位置使用。ContainerRegistry.Resolve应该只在这些 Getters 中找到,所以如果你看到它在其他任何地方使用,请与该开发人员联系,以避免在难以测试的地方传播它的使用。该模式完全可测试单元测试,方法是实例化被测试的类并通过公共 setter 提供模拟。(同样,您只需为测试预期触发的依赖项提供模拟。对于测试代码,可以将容器注册表设置为通过在夹具设置过程中注册拦截来引发 Resolve 调用。

这不遵循正常的 DI 模式。但是,如果其他解决方案失败,这可能会有所帮助。只需使用 DI 执行绑定:

MyDIFramework.Bind<IDataRepository>().To<DataRepository>();

如果您使用的是Autofac,它将如下所示:

builder.RegisterType<DataRepository>().As<IDataRepository>();

然后,您可以在需要时解决它:

var dataRepository = DependencyResolver.Current.GetService<IDataRepository>();

这样,您可以保持无参数。

相关内容

最新更新