IOC - 如何处理更改的依赖项

时间:2017-10-13 08:42:37

标签: c# dependency-injection inversion-of-control

假设我们有以下服务类:

PersonService.cs

public class PersonService : IPersonService
{
    private readonly IPersonRepository _repository;

    public PersonService(IPersonRepository repository)
    {
        _repository = repository;
    }

    /* Interface members here... */
}

此服务类取决于IPersonRepository。在我们的示例中,此存储库将处理文件连接:

FilePersonRepository.cs

public class FilePersonRepository : IPersonRepository
{
    private readonly string _filePath;

    public FilePersonRepository (string filePath)
    {
        _filePath = filePath;
    }

    /* Interface members here... */
}

此存储库依赖于文件路径,该路径是确定应在此存储库中处理哪个文件所必需的。

这些类连接在一个容器中:

public static void ConfigureContainer(MyIocContainer container)
{
    container.Register<IPersonRepository, FilePersonRepository>(@"C:\temp\file.txt");
    container.Register<IPersonService, PersonService>();
    container.Register<MainViewModel>();
}

现在,如果我使用静态路径(例如在配置文件中),一切都很好,这个路径只注入此类构造函数一次。

但是如果我有一个ViewModel,会在整个应用程序中持续存在,并且这个使用已注册的服务类,会发生什么。并且文件路径必须通过打开文件夹对话框进行更改。如何处理?

我认为在我的存储库中使用带有get / set的Property或者创建一个引用static string上的路径的类可能不那么干净。

有什么建议吗?

1 个答案:

答案 0 :(得分:1)

如何解决您的问题有很多解决方案,不可能说哪一个是最好的。但我确信最佳做法是避免动态依赖。

我个人会这样做:

1300

几乎每个存储都有某种连接字符串,因此该接口应适用于大多数其他可能的实现(Mongo,SQL,Azure表)。

您的应用程序引导程序可以指定要使用的配置对话框。例如:

public interface IRepositoryConnectionString
{
    void SetConnectionString(string connectionString);
}

public interface IPersonRepository : IRepositoryConnectionString ...

public class FilePersonRepository : IPersonRepository
{
    /* file related private fields here */

    public FilePersonRepository ()
    {
        SetConnectionString(ConfigurationManager.ConnectionStrings[
            "FilePersonRepository.ConnectionString"]);
    }

    public SetConnectionString(string connectionString)
    {
         /* do all required stuf like flush previous file, open file, etc...  */ 
    }

    /* Interface members here... */
}