c# - 统一注册相互覆盖

标签 c# unity-container

我在 C# 中使用 Unity。我有一个名为 IConnectionStringLoader 的接口(interface),它有两个派生接口(interface)。

public interface IConnectionStringLoader
{
    string Get();
    void Write();
}

public interface IDbConnectionStringLoader : IConnectionStringLoader
{
}

public interface IMetaDataConnectionStringLoader : IConnectionStringLoader
{
}

它只有一个实现:

public class ConnectionStringLoader : IDbConnectionStringLoader, IMetaDataConnectionStringLoader
{
    private readonly string _connectionStringName;

    public ConnectionStringLoader(string connectionStringName)
    {
        _connectionStringName = connectionStringName;
    }

    public string Get()
    {
        var cs = ConfigurationManager.ConnectionStrings[_connectionStringName];
        if (cs != null)
        {
            return cs.ConnectionString;
        }
        return null;
    }

    public void Write()
    {
        Console.WriteLine(_connectionStringName);
    }
}

我的注册是这样的:

container.RegisterType<IMetaDataConnectionStringLoader, ConnectionStringLoader>(new InjectionConstructor("MetaConnection"));
container.RegisterType<IDbConnectionStringLoader, ConnectionStringLoader>(new InjectionConstructor("DbConnection"));

接口(interface)的要点是我可以在我的类中注入(inject)不同的接口(interface)并为每个实现获取正确的连接字符串。 但问题是无论最后完成什么注册都会覆盖之前的。

var foo = _container.Resolve<IDbConnectionStringLoader>();
var bar = _container.Resolve<IMetaDataConnectionStringLoader>();
foo.Write();
bar.Write();

输出是:

DbConnection 
DbConnection

如果我颠倒注册顺序,输出将是 MetaConnection 两次。所以到目前为止我的结论是最后一次注册会覆盖之前的注册。但是,如果我将实现更改为派生类,它会起作用:

public class SomeOtherConnectionStringLoader : ConnectionStringLoader
{
    public ConnectionStringLoaderImpl(string connectionStringName) : base(connectionStringName)
    {
    }
}

并更改注册:

container.RegisterType<IMetaDataConnectionStringLoader, ConnectionStringLoader>(new InjectionConstructor("MetaConnection"));
container.RegisterType<IDbConnectionStringLoader, SomeOtherConnectionStringLoader >(new InjectionConstructor("DbConnection"));

现在一切正常,但我不明白为什么。我尝试过不同的 lifetimemanagers,但结果相同。我原以为 Unity 会尝试根据接口(interface)使用“正确”的注入(inject)参数创建 ConnectionStringLoader 的实例,但这里似乎还有一些其他逻辑在起作用。

注册相互覆盖的原因有什么建议吗?

最佳答案

老实说,您使用接口(interface)的方式对我来说很奇怪,因为有两个接口(interface)仅由同一个类实现。我会发现更自然地遵循使用注册名称的下一种方法:

// If it is a loader the Write method makes no sense (IConnectionStringRepository?)
public interface IConnectionStringLoader
{
    string Get();
    void Write();
}

public class ConnectionStringLoader : IConnectionStringLoader
{
    private readonly string _connectionStringName;

    public ConnectionStringLoader(string connectionStringName)
    {
        _connectionStringName = connectionStringName;
    }

    public string Get()
    {
        var cs = ConfigurationManager.ConnectionStrings[_connectionStringName];
        if (cs != null)
        {
            return cs.ConnectionString;
        }
        return null;
    }

    public void Write()
    {
        Console.WriteLine(_connectionStringName);
    }
}

注册:

container.RegisterType<IConnectionStringLoader, ConnectionStringLoader>("Database", new InjectionConstructor("MetaConnection"));
container.RegisterType<IConnectionStringLoader, ConnectionStringLoader>("Metadata", new InjectionConstructor("DbConnection"));

决议:

var foo = _container.Resolve<IConnectionStringLoader>("Database");
var bar = _container.Resolve<IConnectionStringLoader>("Metadata");
foo.Write();
bar.Write();

关于c# - 统一注册相互覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36284738/

相关文章:

c# - 我没有解决的类型的 Unity 注册错误

c# - 如何使用 Unity 解析接口(interface)集合?

c# - 在哪里存储可编辑的配置参数

c# - 如何使用 RegEx 删除可能嵌套的括号?

c# - 我们可以用自定义异常做什么?

c# - 我应该对这个类进行单元测试吗?

c# - 统一: The type LogWriter cannot be constructed

c# - 统一配置约定

user-interface - 如何在Unity顶部显示ui元素

c# - Autofac - 在解析时在 .OnActivated 方法中传递一个值