Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 类内部实例化与依赖项注入(用于可测试性)_C#_Unit Testing_Dependency Injection - Fatal编程技术网

C# 类内部实例化与依赖项注入(用于可测试性)

C# 类内部实例化与依赖项注入(用于可测试性),c#,unit-testing,dependency-injection,C#,Unit Testing,Dependency Injection,这是一个非常合成的示例,但是我在生产代码中有类似的条件 该计划将申请人转换为员工。 在循环中,我们称之为AccountConvertor的具体专用实现,它聚合在申请者类中(例如,ManagerAccountConvertorforManager)。我们极不可能使用除ManagerAccountConvertor以外的其他工具来转换Manager。每次都为concrete manager注入converter而不是保持内联实例化并按原样测试它,这有什么意义吗 class Program {

这是一个非常合成的示例,但是我在生产代码中有类似的条件

该计划将申请人转换为员工。 在循环中,我们称之为AccountConvertor的具体专用实现,它聚合在申请者类中(例如,
ManagerAccountConvertor
for
Manager
)。我们极不可能使用除
ManagerAccountConvertor
以外的其他工具来转换
Manager
。每次都为concrete manager注入converter而不是保持内联实例化并按原样测试它,这有什么意义吗

class Program
{
    static void Main(string[] args)
    {
        List<IApplicant> applicants = new List<IApplicant>
        {
            new Clerk {FirstName = "Nik", LastName = "Corey"},
            new Manager {FirstName = "Sue", LastName = "Storm"},
            new Executive {FirstName = "Nancy", LastName = "Roman"}
        };

        List<Employee> employees = new List<Employee>();

        foreach (var ap in applicants)
        {
            Employee employee = ap.AccountConvertor.Convert();

            employees.Add(employee);
        }

        foreach (var emp in employees)
        {
            Console.WriteLine($"{emp.FirstName} {emp.LastName}: {emp.EmailAddress} IsManager: {emp.IsManager} IsExecutive: {emp.IsExecutive}");
        }

        Console.ReadLine();
    }
}

public interface IApplicant
{
    string FirstName { get; set; }
    string LastName { get; set; }
    IAccountConvertor AccountConvertor { get; set; }
}

public interface IAccountConvertor
{
    Employee Convert();
}
类程序
{
静态void Main(字符串[]参数)
{
名单申请人=新名单
{
新职员{FirstName=“Nik”,LastName=“Corey”},
新经理{FirstName=“Sue”,LastName=“Storm”},
新主管{FirstName=“Nancy”,LastName=“Roman”}
};
列出员工=新列表();
foreach(申请人中的var ap)
{
Employee=ap.AccountConvertor.Convert();
employees.Add(employees);
}
foreach(员工中的var emp)
{
Console.WriteLine($“{emp.FirstName}{emp.LastName}:{emp.EmailAddress}IsManager:{emp.IsManager}IsExecutive:{emp.IsExecutive}”);
}
Console.ReadLine();
}
}
公共接口应用程序
{
字符串名{get;set;}
字符串LastName{get;set;}
IAccountConvertor AccountConvertor{get;set;}
}
公共接口计数器转换器
{
员工转换();
}

如果IAccountConverter对于iaapplicator的所有实现都是相同的,那么不必为每个员工实例实例化IAccountConverter的具体实现,而只为每个员工类型实例化一个,这将是一个性能优势。从注入存储库检索实例也有开销。你必须考虑开销对于解决方案的数量或雇员是否足够重要。

如果你坚持这个模式,你就不能独立地测试这些单元,而且你也不可能从<代码>管理器转换器> /代码>中改变。调用
AccountConvertor.Convert()
中的参数也是多余的。请根据某些参数或属性使用某种形式的约定注入具体实现。在注册实现时,将生存期注册为
作用域
,以便使用相同的实例。将
接口
映射到
DTO
类,并使用这些接口注入它们。此问题可能会以主题外或基于观点的方式结束。。。从您的描述来看,AccountConvertor似乎没有外部依赖项;因此,我看不出有什么理由把它放在接口后面,更不用说通过DI注入它了。YMMV.@BarryO'Kane为什么不将转换器和申请人作为一个共同的单元进行测试(集成测试)?此外,我们还可以单独对转换器进行单元测试。这正是我最初发布这个问题的原因。在任何地方都应用SOLID中的“D”而不进行思考,这不是很愚蠢吗?是的,这个论点被修正了。性能与我的问题无关。这一切都是关于设计的简单性。