根据 Servicestack 中的请求解决依赖关系

Resolving Dependencies based on request in Servicestack

我有一个 Servicestack Api,我需要关于注入依赖项的建议\想法。

我的Api需要根据请求参数调用合适的依赖

我已经注册了如下依赖


    public class AppHost : AppHostBase
    {
        //default code
    
        public override void Configure(Container container)
        {
            container.Register<ITravelManager>("Air", new AirTravelManager());
            container.Register<ITravelManager>("Road", new RoadTravelManager());
        }
    }

服务看起来像:

public class TravelService:Service
{
    private readonly ITravelManager traveleManager;

    public TravelService(ILogService logService) 
    {
        
    }
    
    public TravelByAir Post(TravelByAirReq request)
    {
        traveleManager= ServiceStackHost.Instance.Container.ResolveNamed<ITravelManager >("Air");
        traveleManager.BooKTickets();
    }
    
    public TravelByRoad Post(TravelByRoadReq request)
    {
        traveleManager= ServiceStackHost.Instance.Container.ResolveNamed<ITravelManager >("Road");
        traveleManager.BooKTickets()
    }
}

我的经理class看起来像

public interface ITravelServiceManager 
{
     Tickets BooKTickets();
}
public class AirTravelManager
{
     Tickets BooKTickets()
     {
          ....
     }
}
public class SeaTravelManager
{
     Tickets BooKTickets()
     {
          ....
     }
}

以这种方式解析 traveleManager,看起来像反模式。 有没有更好的方法\模式来解决 traveleManager 而无需使用服务定位器。

我不会注册多个命名的 ITravelManager 实例,而是注册一个 TravelServiceManager 实例,根据请求确定哪个 ITravelManager 到 return,例如:

public override void Configure(Container container)
{
    container.Register(new TravelServiceManager(
        new AirTravelManager(), new RoadTravelManager()));
}

其中 TravelServiceManager 有一个方法 return ITravelManager 用于该请求,例如:

public interface ITravelManager
{
    Tickets BooKTickets();
}
public class TravelServiceManager
{
    private readonly AirTravelManager air;
    private readonly RoadTravelManager road;

    public TravelServiceManager(AirTravelManager air, RoadTravelManager road)
    {
        this.air = air;
        this.road = road;
    }

    public ITravelManager GetTravelManager(IRequest req) => req.Dto switch
    {
        TravelByAirReq => air,
        TravelByRoadReq => road,
        _ => throw new NotSupportedException(
            $"Can't resolve {nameof(ITravelManager)} for request {req.Dto.GetType().Name}")
    };
}
public class AirTravelManager : ITravelManager
{
    public Tickets BooKTickets() => null;
}
public class RoadTravelManager : ITravelManager
{
    public Tickets BooKTickets() => null;
}

这样您就可以将 TravelServiceManager 解析为服务中的正常依赖项:

public class TravelService : Service
{
    public TravelServiceManager TravelServiceManager { get; set; } 

    public object Post(TravelByAirReq request)
    {
        var travelManager = TravelServiceManager.GetTravelManager(base.Request);
        travelManager.BooKTickets();
        //...
    }        
}

但是如果您有多个 ITravelManager,我会删除单独的 Request DTO 列表并使用自定义属性来注释哪个 TravelManager 用于哪个请求,例如:

[TravelManager("air")]
public class TravelByAirReq {}

[TravelManager("road")]
public class TravelByRoadReq {}

//...

然后使用该请求的元数据属性来确定使用哪个 ITravelManager,例如:

public class TravelServiceManager
{
    private Dictionary<string, ITravelManager> travelManagers;
    public TravelServiceManager(Dictionary<string, ITravelManager> travelManagers) => 
        this.travelManagers = travelManagers;

    public ITravelManager GetTravelManager(IRequest req)
    {
        var key = req.Dto.GetType().FirstAttribute<TravelManagerAttribute>()?.Name;
        if (key != null && travelManagers.TryGetValue(key, out var travelManager))
            return travelManager;

        throw new NotSupportedException(
            $"Can't resolve {nameof(ITravelManager)} for request {req.Dto.GetType().Name}");
    }

}