我可以提供一些关于“关注点分离”的指导。我正在开发一个假期预订应用程序,以尝试提高我的 DI 和 TDD 知识,我有两个独立的存储库“Allocation”和“PublicHoliday”,它们都有自己的业务逻辑类 AllocationLogic 和 PublicHolidayLogic。
AllocationLogic 有一个名为CalculateWorkingDays 的方法,该方法计算用户必须为给定范围(分配对象的开始日期和结束日期属性)分配假期的日期。
PublicHolidayLogic 有一个名为 PublicHolidaysForTheYear 的方法,它可以获取一年中的所有银行假日。而不是将此方法中的代码复制到CalculateWorkingDays 方法中,我想从CalculateworkingDays 方法中的PublicHolidayLogic 类中调用它。
我的问题是可以在 CalculateworkingDays 方法中创建 publicHolidayLogic 类的实例,通过 Allocation 构造函数传入所需的存储库吗?或者我应该在分配构造函数中将接口传递给 publicholidaylogic。
我希望前者,但我附上了我的代码,任何帮助将不胜感激
-- 公共假期班
public class PublicHolidayLogic : IPublicHolidayLogic
{
private IPublicHolidayRepository _publicHolidayRepository;
public PublicHolidayLogic(IPublicHolidayRepository publicHolidayRepo)
{
_publicHolidayRepository = publicHolidayRepo;
}
public System.Collections.Generic.IEnumerable<Domain.Models.PublicHoliday>
PublicHolidaysForTheYear(int year, int countryId)
{
var returnedDates = _publicHolidayRepository.Enumerable()
.Where(t => t.StartDate.Year == year && t.CountryId == countryId).ToList();
List<Domain.Models.PublicHoliday> _result = new List<Domain.Models.PublicHoliday>();
foreach(Domain.Models.PublicHoliday p in returnedDates)
{
if (!_result.Any(t => t.Name == p.Name && t.StartDate == p.StartDate))
_result.Add(p);
}
return _result.AsEnumerable();
}
}
-- 分配类
public class AllocationLogic : IAllocationLogic
{
private IAllocationRepository _allocationRepository;
private IPublicHolidayRepository _publicHolidayRepository;
public AllocationLogic(IAllocationRepository allocationRepo,
IPublicHolidayRepository publicHolidayRepository)
{
_allocationRepository = allocationRepo;
_publicHolidayRepository = publicHolidayRepository;
}
public int CalculateWorkingDays(Domain.Models.Allocation allocation)
{
//TODO A Better way of doing this would be nice.
List<DateTime> _dates = new List<DateTime>();
List<DateTime> _result = new List<DateTime>();
//Monday To Friday Only
for (DateTime i = allocation.StartDate; i <= allocation.EndDate; i = i.AddDays(1))
{
if (i.DayOfWeek != DayOfWeek.Saturday
&& i.DayOfWeek != DayOfWeek.Sunday
&& !_dates.Contains(i))
_dates.Add(i);
}
//Remove Bank Holidays
if (_publicHolidayRepository != null)
{
IEnumerable<Domain.Models.PublicHoliday> _holidays
= new PublicHolidayLogic(_publicHolidayRepository)
.PublicHolidaysForTheYear(allocation.StartDate.Year, allocation.User.CountryId);
if (_holidays.Count() > 0)
{
foreach (DateTime d in _dates)
{
if (!_holidays.Any(t => t.StartDate == d))
{
_result.Add(d);
}
}
}
else
{
_result.AddRange(_dates);
}
}
else
{
_result.AddRange(_dates);
}
return _result.Count;
}
}
-- 分配测试类
[TestClass]
public class AllocationLogicTests
{
[TestMethod]
public void CalculateWorkingDaysOnly()
{
//Holiday
var allocation = new Allocation {
StartDate = new DateTime(2013, 1, 7),
EndDate = new DateTime(2013, 1, 18)
};
var user = new User { CountryId = 1 };
var allocationLogic = new AllocationLogic(null,null);
allocation.User = user;
int result = allocationLogic.CalculateWorkingDays(allocation);
Assert.AreEqual(10, result);
}
[TestMethod]
public void CalculateWorkingDaysWithBankHoliday()
{
//Holiday
var allocation = new Allocation {
StartDate = new DateTime(2013, 1, 7),
EndDate = new DateTime(2013, 1, 18)
};
var publicHoliday = new List<PublicHoliday> {
new PublicHoliday { CountryId = 1, StartDate = new DateTime(2013, 1, 10),
Name = "My Bank Holiday" }
};
var user = new User { CountryId = 1 };
var mock = new Mock<IPublicHolidayRepository>();
mock.Setup(s => s.Enumerable()).Returns(publicHoliday.AsEnumerable());
allocation.User = user;
var allocationLogic = new AllocationLogic(null,mock.Object);
int result = allocationLogic.CalculateWorkingDays(allocation);
Assert.AreEqual(9, result);
}
}