C# 如何向域实体注入服务以及如何持久化实体

C# 如何向域实体注入服务以及如何持久化实体,c#,entity-framework,dependency-injection,domain-driven-design,clean-architecture,C#,Entity Framework,Dependency Injection,Domain Driven Design,Clean Architecture,我正在创建一个旅游计划。巡更始终以相同的坐标开始和结束。在开始和结束之间,有Stops。站点包含特定的景点,可在游览期间+游览时间内游览。在为游览添加景点时,我会插入一个新站点,并根据站点之间的距离重新计算站点的到达时间。为此,我在private recreactestoptimes(int fromIdx)方法中使用注入的ITravelService实例 我的问题如下:在我希望通过ORM在数据库中持久化一个巡更对象之前,这是有效的。由于专用ITravelService,检索后该功能将丢失。我

我正在创建一个旅游计划。
巡更
始终以相同的坐标开始和结束。在开始和结束之间,有
Stop
s。站点包含特定的
景点
,可在游览期间+游览时间内游览。在为游览添加景点时,我会插入一个新站点,并根据站点之间的距离重新计算站点的到达时间。为此,我在
private recreactestoptimes(int fromIdx)
方法中使用注入的
ITravelService
实例


我的问题如下:在我希望通过ORM在数据库中持久化一个巡更对象之前,这是有效的。由于专用ITravelService,检索后该功能将丢失。我曾想过通过InsertSight/RemoveSight/RemoveStop方法注入serivce,但随后我需要用我创建的每个修改停止的公共方法注入它。有没有更好的方法将这样的服务注入实体?或者我应该注射吗?如果没有,我如何获得相同的功能(重新计算其站点)

公共接口ITravelService
{
公共时间跨度计算时间间隔(坐标从,坐标到);
}
公务舱旅游:伊图尔
{
私有只读列表\u停止;
私人ITravelService(u travelService),;
公共IReadOnlyList停止{get{return\u Stops;}}
public bool的限制为{get{return}stops.Last().TimeRange.From<(StartTime.TimeOfDay+Length);}
公共游览(日期时间开始时间、时间跨度长度、坐标开始、ITravelService travelService)
{
开始时间=开始时间;
长度=长度;
Stop firstStop=新的停止(开始,新的时间范围(startTime.TimeOfDay,startTime.TimeOfDay));
停止lastStop=新停止(开始,新时间范围(startTime.TimeOfDay,startTime.TimeOfDay));
_stops=新列表(){firstStop,lastStop};
}
私有void重新计算选项(int fromIdx)
{
对于(int i=fromIdx;i<\u stops.Count-1;i++)
{
停止电流停止=_停止[i];
Stop nextStop=_停止[i+1];
var travelTime=\u travelService.CalculateTimeBeween(currentStop.Coordinates,nextStop.Coordinates);
nextStop.Arrival=currentStop.TimeRange.To+travelTime;
}
}
公共无效插入瞄准具(瞄准具,整数索引)
{
如果(index==0 | | index==Stops.Count)抛出新的ArgumentOutOfRangeException(“不能在第一个停止之前或最后一个停止之后插入”);
_插入(索引,新的观察窗(观察窗,开始时间,星期几));
重新计算最佳方案(指数-1);
}
公共空视移除(视景移除)
{
如果(_stops.Count==2)抛出新的ArgumentException(“视线不在巡视中”);
int-idx=1;
while(((_stops[idx]as SightStop).Sight!=sightToRemove)和&idx 0和&index<\u stops.Count-1)
{
_停止。移除(索引);
重新计算最佳方案(指数-1);
}
其他的
{
抛出新ArgumentOutOfRangeException(“索引超出范围”);
}
}
公共IReadOnlyList观光旅游
{
得到
{
返回_stops.Where(stop=>stop为SightStop)。选择(x=>(x为SightStop.Sight).ToList();
}
}
}

实体表示数据状态,只应表示数据状态。如果需要,让您的重新计算服务接收实体、检查并修改它们。除了验证数据级别的关注点(必需的与可选的、字符串长度等)之外,业务逻辑应该被排除在实体之外

您可能会遇到的一个问题是,您在旅行中依赖于站点的顺序。根据实体中集合的顺序,这很可能是不可靠的,除非在插入和删除停止时显式引入类似StopNumber的内容,并在处理子集合时使用
OrderBy
子句。添加或删除站点的操作包括插入/删除元素和更新行程时间。也可以将其移动到服务中

public interface ITravelService
{
    public void UpdateTravelTimes(Tour tour);
    public void AddSightStopToTour(Tour tour, Sight sight);
    public void RemoveSightStopFromTour(Tour tour, Sight sight);
}
我甚至建议避免将实体传递到方法中,而是传递实体的ID。该服务可以保存对存储库或DbContext的依赖关系,这可以确保加载实体时会加载必要的集合,而不可能在没有停止的情况下接收巡更,然后触发延迟加载

public interface ITravelService
{
    public Tour UpdateTravelTimes(int tourId);
    public Tour AddSightStopToTour(int tourId, int sightId);
    public Tour RemoveSightStopFromTour(int tourId, int sightId);
}

public class TravelService : ITravelSerivce
{
    public Tour UpdateTravelTimes(int tourId, int fromIndex)
    {
        if(fromIndex < 0) 
            throw new IndexOutOfRangeException("fromIndex < 0");

        var tour = Context.Tours
            .Include(x => x.Stops)
            .Single(x => x.TourId == tourId);
           
        if(fromIndex >= tour.Stops.Count())
            return tour; // Nothing to do.

        var orderedStops = tour.Stops
            .OrderBy(x => x.StopNumber)
            .ToList();

        for (int i = fromIndex; i < orderedStops.Count - 1; i++)
        {
            Stop currentStop = orderedStops[i];
            Stop nextStop = orderedStops[i + 1];
            var travelTime = calculateTimeBetween(currentStop.Coordinates, nextStop.Coordinates);
            nextStop.Arrival = currentStop.TimeRange.To + travelTime;
        }

        return tour;
    }
}
公共接口ITravelService
{
公共旅游更新行程时间(int tourId);
公共旅游附加观光旅游(国际旅游、国际观光);
公共旅游取消了StopFromTour(int tourId、int sightId);
}
公务舱旅行服务:iTravelService
{
公共巡更更新行程时间(int tourId、int fromIndex)
{
如果(从索引<0)
抛出新的IndexOutOfRangeException(“fromIndex<0”);
var tour=Context.Tours
.包括(x=>x个站点)
.单个(x=>x.TourId==TourId);
if(fromIndex>=tour.Stops.Count())
回程;//无事可做。
var orderedStops=tour.Stops
.OrderBy(x=>x.StopNumber)
.ToList();
for(inti=fromIndex;i
上面的示例假设DbContext作为依赖项注入,或者可以从工作单元解析

阿迪
public interface ITravelService
{
    public Tour UpdateTravelTimes(int tourId);
    public Tour AddSightStopToTour(int tourId, int sightId);
    public Tour RemoveSightStopFromTour(int tourId, int sightId);
}

public class TravelService : ITravelSerivce
{
    public Tour UpdateTravelTimes(int tourId, int fromIndex)
    {
        if(fromIndex < 0) 
            throw new IndexOutOfRangeException("fromIndex < 0");

        var tour = Context.Tours
            .Include(x => x.Stops)
            .Single(x => x.TourId == tourId);
           
        if(fromIndex >= tour.Stops.Count())
            return tour; // Nothing to do.

        var orderedStops = tour.Stops
            .OrderBy(x => x.StopNumber)
            .ToList();

        for (int i = fromIndex; i < orderedStops.Count - 1; i++)
        {
            Stop currentStop = orderedStops[i];
            Stop nextStop = orderedStops[i + 1];
            var travelTime = calculateTimeBetween(currentStop.Coordinates, nextStop.Coordinates);
            nextStop.Arrival = currentStop.TimeRange.To + travelTime;
        }

        return tour;
    }
}