为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
牧羊人nacy 2021-10-24 16:53:41
我目前正在学习 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 的参数?很高兴看到如何解决这个问题的例子。
查看完整描述

3 回答

?
一只甜甜圈

TA贡献1836条经验 获得超5个赞

首先,将您的代码注入一个实例WorkYear不会使您的代码独立WorkYear于Employee仍然知道此类的(例如在列表 List<WorkYear> WorkYears中),因此,如果您需要 DI,您应该与代表此类的接口进行对话IWorkYear(和这里该列表将List<IWorkYear> WorkYears改为)。


现在用于注入和实例化:


制作一个工厂类,如:


public static class MyFactory

{

    public static object Create(Type classType, object[] data = null)

    {

        // create the class by reflection

    }

}

(要通过反射创建类,请检查: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});


查看完整回答
反对 回复 2021-10-24
  • 3 回答
  • 0 关注
  • 161 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信