在Unity中注册泛型

时间:2016-05-18 18:31:34

标签: c# .net generics dependency-injection unity-container

我在项目中有一些Unity DI导致依赖注册单元测试失败。我认为这是因为我在注册泛型时有错误的语法。我想这可能是我没有看到的其他东西。无论如何,我试图按照[本文] [1]来注册泛型,但我发现它缺乏和令人困惑,所以我还没有到达那里。它提到了像InjectionConstructorGenericaParameter这样的Unity类,但在尝试使用它们时,我遇到了各种编译时错误。我也没有在这里找到任何东西来澄清事情。我希望有人可以对如何注册这些内容有更明确的解释(或者其他一些答案,如果这不是问题)。

以下是一些相关代码:

首先是我的顶级界面,它将被客户端代码注入并使用,指定T的类型。

namespace Elided.Extraction.Interfaces
{
    public interface IDataExtractionService<out T>
    {
        T GetData(Stream stream);
    }
}

下一个类是具有可注入IDataExtractor的实现:

namespace Elided.Extraction
{
    public class DataExtractionService<T> : IDataExtractionService<T>
    {
        private readonly IDataExtractor<T> extractor;

        internal DataExtractionService(IDataExtractor<T> extractor)
        {
            this.extractor = extractor;
        }

        public T GetData(Stream workbookStream)
        {
            // elided
            return this.extractor.GetData(elidedArgument)
        }
    }
}

这是IDataExtractor的界面:

namespace Elided.Extraction.Behaviors.Interfaces
{
    internal interface IDataExtractor<out T>
    {
        T GetData(object elidedArgument);
    }
}

这是IDataExtractor的实现。它是DataSet类型的实现,但其想法是可以存在许多实现,允许客户端代码具有可注入的IDataExtractionService或任何其他类型的写入提取器实现。

namespace Elided.Extraction.Behaviors
{
    internal class DataSetExtractor : IDataExtractor<DataSet>
    {
        public DataSet GetData(object elidedArgument)
        {
            // implementation elided
            // returns a DataSet
        }
    }
}

最后,这是我的注册代码(与上述内容相同的程序集),我认为它不起作用:

public void RegisterDependencies(IDependencyContainer container)
{
    container.RegisterType(typeof(IDataExtractionService<>), typeof(DataExtractionService<>));
    container.RegisterType(typeof(IDataExtractor<DataSet>), typeof(DataSetExtractor));
}

更新:特定错误消息来自单元测试的异常抛出:

  

在解决时发生异常:例外情况是:   InvalidOperationException - 类型DataExtractionService`1   无法建造。您必须配置容器以提供此功能   值。 [1]:   https://msdn.microsoft.com/en-us/library/ff660936(v=pandp.20).aspx

1 个答案:

答案 0 :(得分:1)

我粘贴了你的代码并创建了一个单元测试:

<td> {{ record.jsonData | prettyprint }} </td>

第一个失败是因为 [TestMethod] public void TestUnityConfiguration() { var container = new UnityContainer(); //This part is copied from your Unity configuration. container.RegisterType(typeof(IDataExtractionService<>), typeof(DataExtractionService<>)); container.RegisterType(typeof(IDataExtractor<DataSet>), typeof(DataSetExtractor)); var x = container.Resolve<IDataExtractionService<DataSet>>(); Assert.IsInstanceOfType(x, typeof(DataExtractionService<DataSet>)); var y = container.Resolve<IDataExtractor<DataSet>>(); Assert.IsInstanceOfType(y, typeof(DataSetExtractor)); } 没有公共构造函数,因此Unity无法创建它。

我尝试使用AssemblyInfo.cs中的条目来使Unity可以看到内部,但这并不起作用。

我还读了一些 - 隐藏的构造函数没有解决方法。请参阅this post

您可以将构造函数设为公开,但是您还需要公开DataExtractionService。通过这种改变,我能够解决两个注册的实例。