根据 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}");
}
}
我有一个 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}");
}
}