![](/img/trans.png)
[英]ServiceStack WebApi File Download From Another Service (Pass-Through)
[英]Calling one ServiceStack 4 service from another with a file upload thrown in for fun
我在4.0.31中有一個工作服務,看起來像這樣:
public object Post(MyDTO request)
{
foreach (var uploadedFile in base.Request.Files)
{
... do something ...
}
return new MyDTOResponse();
}
一切都很好,我很高興!
但是現在,我想從另一個服務中調用相同的服務方法,顯然,這樣做的方法是:
public object Post(MyOtherDTO request)
{
var myService = base.ResolveService<MyService>();
// now I call some new method I wrote to bypass the file upload part, since
// myService.Post() doesn't know about the file upload part
var myResponse = myService.NewMethodThatLetsMePassAStreamToTheOtherService(streamData);
... do other stuff...
return new MyOtherDTOResponse();
}
雖然我對此並不滿意 ,但它確實在兩個服務之間創建了硬依賴性,因此,我並不像通常使用ServiceStack那樣激動 !
有沒有更優雅的方式將它們組合在一起? 我可能只是想念一些非常非常明顯的東西...
我不清楚問題是什么,如果要在服務之間共享邏輯的話? 那么您可以從每個服務類中提取通用邏輯,並在兩個服務中引用共享代碼。
如果不需要依賴,我將在可重用的擴展方法后面重構共享代碼。
如果需要依賴關系,我將在兩個服務都依賴的共享邏輯類后面重構它,請參閱MVC和ServiceStack之間的共享邏輯中的IGreeter
示例:
public class MyService1 : Service
{
public ISharedDep SharedDep { get; set]
public object Any(Request1 request)
{
//...
}
}
public class MyService2 : Service
{
public ISharedDep SharedDep { get; set]
public object Any(Request2 request)
{
//...
}
}
如果是許多需要base.Request
上下文的服務使用的通用代碼,則可以將其移至通用Service基類:
public class MyServiceBase : Service
{
public ISharedDep SharedDep { get; set]
public object SharedMethod(object request)
{
//...
}
}
public class MyServices1 : MyServiceBase { ... }
public class MyServices2 : MyServiceBase { ... }
如果您不想使用基類,則也可以在擴展方法后面對其進行重構:
public static void MyServiceExtensions
{
public static object SharedMethod(this IServicBase service, object request)
{
var sharedDep = service.TryResolve<ISharedDep>();
return sharedDep.SharedMethodWithRequestCtx(request, service.Request);
}
}
如果問題是關於調用服務的松散耦合方式而不涉及實現本身,則可以使用ServiceController執行Request DTO:
public class MyService : Service
{
public object Any(Request requestDto)
{
var altDto = new AltRequest { Id = requestDto.Id };
var response = HostContext.ServiceController.Execute(altDto, base.Request);
//...
}
}
注意:此API在v4.0.32 +中可以作為
base.ExecuteRequest(requestDto)
使用。
如果問題是如何執行處理文件上傳的服務, 則嵌入式版本的HttpBenchmarks中有一個示例,該示例顯示如何調用使用自定義請求上下文(使用本地FileSystem文件)來處理HTTP文件上傳的服務:
using (var admin = Resolve<AdminServices>())
{
//...
var dir = new FileSystemVirtualPathProvider(this, Config.WebHostPhysicalPath);
var files = dir.GetAllMatchingFiles("*.txt")
.Concat(dir.GetAllMatchingFiles("*.zip"));
admin.Request = new BasicRequest
{
Files = files.Map(x => new HttpFile {
ContentLength = x.Length,
ContentType = MimeTypes.GetMimeType(x.Name),
FileName = x.Name,
InputStream = x.OpenRead(),
} as IHttpFile).ToArray()
};
if (admin.Request.Files.Length > 0)
{
admin.Post(new UploadTestResults
{
TestPlanId = 1,
TestRunId = testRun.Id,
CreateNewTestRuns = true,
});
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.