C# 从一个ServiceStack 4服务调用另一个ServiceStack 4服务时,为了好玩,会抛出一个文件上载
我在4.0.31中有一个工作服务,如下所示:C# 从一个ServiceStack 4服务调用另一个ServiceStack 4服务时,为了好玩,会抛出一个文件上载,c#,
servicestack,C#,
servicestack,我在4.0.31中有一个工作服务,如下所示: public object Post(MyDTO request) { foreach (var uploadedFile in base.Request.Files) { ... do something ... } return new MyDTOResponse(); } 一切都很好,我很高兴 但是现在,我想从另一个服务中调用同一个服务方法,实现这一点的方法显然是: public object Post(M
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();
}
public object Post(MyOtherDTO请求)
{
var myService=base.ResolveService();
//现在我调用我编写的一些新方法来绕过文件上传部分,因为
//myService.Post()不知道文件上传部分
var myResponse=myService.newmethodthat允许SME将流传递给其他服务(streamData);
…做其他事情。。。
返回新的MyTherdToResponse();
}
虽然我对此并不不满,但它确实在两个服务之间创建了一个硬依赖关系,因此我不会像往常一样对ServiceStack感到兴奋
有没有一种更优雅的方式来组合这一切?我可能只是错过了一些非常非常明显的东西…我不完全清楚问题是什么,如果是如何在服务之间共享逻辑?然后,您可以从每个服务类中提取公共逻辑,并引用两个服务中的共享代码 如果不需要依赖项,我将重构可重用扩展方法背后的共享代码 如果需要依赖项,我将在两个服务中都是依赖项的共享逻辑类后面对其进行重构,请参见中的
IGreeter
示例:
使用基类使用请求上下文的共享逻辑
如果许多服务使用的是公共代码,需要base.Request
上下文,则可以将其移动到公共服务基类:
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);
}
}
注意:此API在v4.0.32+中作为base.ExecuteRequest(requestDto)
提供
将文件上载到内存中的HTTP服务
如果问题是如何执行处理文件上载的服务,则会显示如何调用使用本地文件系统文件的自定义请求上下文处理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,
});
}
}
使用(var admin=Resolve())
{
//...
var dir=new FileSystemVirtualPathProvider(这个,Config.WebHostPhysicalPath);
var files=dir.GetAllMatchingFiles(“*.txt”)
.Concat(dir.GetAllMatchingFiles(“*.zip”);
admin.Request=newBasicRequest
{
Files=Files.Map(x=>newhttpfile{
ContentLength=x.长度,
ContentType=MimeTypes.GetMimeType(x.Name),
FileName=x.Name,
InputStream=x.OpenRead(),
}作为IHttpFile)。ToArray()
};
如果(admin.Request.Files.Length>0)
{
admin.Post(新的上传测试结果)
{
TestPlanId=1,
TestRunId=testRun.Id,
CreateNewTestRuns=true,
});
}
}
和往常一样,我把事情弄得太复杂了。谢谢你的提示。你可能已经猜到了,但是你的“执行请求DTO的松耦合”示例让我回到了正常的Thrilled_with_Servicestack状态!
public class MyService : Service
{
public object Any(Request requestDto)
{
var altDto = new AltRequest { Id = requestDto.Id };
var response = HostContext.ServiceController.Execute(altDto, base.Request);
//...
}
}
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,
});
}
}