从方法中删除条件“new”关键字依赖项

我目前正在学习 DI 和 IoC 原则。所以,我偶然发现了这样一个场景,我有一个无法通过构造函数注入的依赖项。另外,我不能将它作为方法参数传递,因为该实例的创建是有条件的+它只能用它自己的参数实例化。这是我的 Employee 和 WorkYear 类的超级简化版本:


public abstract class Employee

{

    private List<WorkYear> _workYears;

    // other private fields....


    protected Employee(IDependency1 dep, etc...)

    {

         WorkYears = new List<WorkYear>();


         // other components initialization....

    }


    public IEnumerable<WorkYear> WorkYears

    {

        get => _workYears.AsReadOnly();

        private set => _workYears = value.ToList();

    }


    public void StartWorking(DateTime joinedCompany)

    {

        List<PayPeriod> periods = // Calculating periods...

        WorkYear year = WorkYears.FirstOrDefault(y => y.CurrentYear == joinedCompany.Year);


        if (year == null)

        {

            // Here is the problem:

            year = new WorkYear(joinedCompany.Year, this, periods);


            AddYear(year);

        }

        else

        {

            // Logic when year not null

        }


        year.RecalculateAllTime();

    }


    public void AddYear(WorkYear workYear) => _workYears.Add(workYear);


    // More code...

}



public class WorkYear  

    public WorkYear(int currentYear, Employee employee, List<PayPeriod> periods)

    {

        Employee = employee;

        EmployeeId = employee.Id;

        CurrentYear = currentYear;

        PayPeriods = periods ?? new List<PayPeriod>();


        foreach (PayPeriod period in PayPeriods)

        {

            period.WorkYear = this;

            period.WorkYearId = Id;

        }

    }


     // More code...

}

如您所见,如果 Employee 还没有 WorkYear 的新实例,我只需要它。我发现一个线程建议使用简单的工厂类来解决类似的问题。这样的解决方案可以工作,但是如何处理无法实例化 WorkYear 的参数?


很高兴看到如何解决这个问题的例子。


牧羊人nacy
浏览 162回答 3
3回答

一只甜甜圈

首先,将您的代码注入一个实例WorkYear不会使您的代码独立WorkYear于Employee仍然知道此类的(例如在列表 List<WorkYear> WorkYears中),因此,如果您需要 DI,您应该与代表此类的接口进行对话IWorkYear(和这里该列表将List<IWorkYear> WorkYears改为)。现在用于注入和实例化:制作一个工厂类,如:public static class MyFactory{&nbsp; &nbsp; public static object Create(Type classType, object[] data = null)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; // create the class by reflection&nbsp; &nbsp; }}(要通过反射创建类,请检查:Activator.CreateInstance)然后更改方法的签名,StartWorking以便将类型注入到方法中:public void StartWorking(Type workYearType, DateTime joinedCompany)和线:year = new WorkYear(joinedCompany.Year, this, periods);将会 :year = MyFactory.Create(classType, new object[]{ joinedCompany.Year, this, periods});
打开App,查看更多内容
随时随地看视频慕课网APP