具有通用服务的服务结构

我希望有一个通用类型的服务,即 –

public interface IFooService { Task Get(int id); } 

但是,服务结构不允许generics类或generics方法。 我也尝试过类似的东西

 public interface INinjaService : IService, IFooService { } 

但它没有选择inheritance的接口说明

服务类型“Omni.Fabric.Services.NinjaService”未实现任何服务接口。 服务接口是从“Microsoft.ServiceFabric.Services.Remoting.IService”类型派生的接口。

我似乎无法在Service Fabric文档或stackoverflow上找到任何关于generics的引用。 要么它仍然太新,要么我可能走错了路。 有没有人有幸实现这种模式? 可以吗? 它应该完成吗?

NinjaService按要求提供

 public class NinjaService : StatelessService, INinjaService { public NinjaService(StatelessServiceContext serviceContext) : base(serviceContext) { } protected override IEnumerable CreateServiceInstanceListeners() { return new[] { new ServiceInstanceListener(context => this.CreateServiceRemotingListener(context)) }; } public Task Get(int id) { return Task.FromResult(new SuperNinja()); } } 

消耗代码(从Owin WebApi服务调用

  public async Task Get(int key) { try { INinjaService service = ServiceProxy.Create(new Uri("fabric:/Omni.Fabric/Services")); var t = await service.Get(key).ConfigureAwait(false); return t; } catch (Exception ex) { throw; } } 

Service Fabric中的服务可以实现通用接口:

 interface IMyService { T Foo(); } class Stateful1 : StatefulService, IMyService { public Stateful1(StatefulServiceContext context) : base(context) { } public string Foo() { // do foo } } 

这可以。

支持的是远程过程调用(RPC)的通用接口。 这特定于Service Remoting通信堆栈,这是您使用IService和Remoting通信监听器所拥有的。

所以在你的情况下,不,还没有支持generics。 但这是特定服务通信堆栈的限制,而不是一般服务的限制,当然您可以使用任何所需的通信堆栈 。

Service Fabric正在使用此扩展方法来删除非服务类型接口

 internal static class ServiceTypeExtensions { public static Type[] GetServiceInterfaces(this Type serviceType) { List typeList = new List(((IEnumerable)serviceType.GetInterfaces()).Where(t => typeof(IService).IsAssignableFrom(t))); typeList.RemoveAll(t => t.GetNonServiceParentType() != null); return typeList.ToArray(); } internal static Type GetNonServiceParentType(this Type type) { List typeList = new List(type.GetInterfaces()); if (typeList.RemoveAll(t => t == typeof(IService)) == 0) return type; foreach (Type type1 in typeList) { Type serviceParentType = type1.GetNonServiceParentType(); if (serviceParentType != null) return serviceParentType; } return null; } } 

并检查结果

 if (serviceInterfaces.Length == 0 && !serviceType.IsAbstract) throws the exception in question 

所以我找到了解决此案例的方法

 public interface IServiceWrapper : IService { } public interface INinjaService : IServiceWrapper, IFooService { } 

更新

经过一番调查后,我发现代理正在检查所有接口父母是否需要IService,这意味着

  Type serviceParentType = serviceInterfaceType.GetNonServiceParentType(); if (serviceParentType != null) throws another exception 

所以你需要从IService派生IFooService ,目前不支持。

因此不支持generics:(

这个答案可能会迟到,但它可能对某人有所帮助。 我通过确保服务类中实现的每个接口都inheritance自IService来解决这个问题。 在你的情况下,你有以下内容:

 public interface IFooService : IService { Task Get(int id); } public interface INinjaService : IFooService { } public class NinjaService : StatelessService, INinjaService { } 

试试吧,它应该工作。 如果您需要在服务中实现多个接口,我已尝试以下选项:

 public interface MyInterfaceA : IService { } public interface MyInterfaceB : IService { } public class MyServiceAB : StatelessService, MyInterfaceA, MyInterfaceB { } 

要么

 public interface MyInterfaceA : IService { } public interface MyInterfaceB : IService { } public interface MyInterfaceC : MyInterfaceA, MyInterfaaceB { } public class MyServiceC : StatelessService, MyInterfaceC { } 

希望有所帮助。

由于我想从一个服务到另一个服务进行调用,我所做的解决方法是传递一个带有Type名称的字符串,并用reflection调用另一个方法。

  public async Task GetResultAsync(Site site, string indexableType, SearchQuery searchQuery) { using (var provider = new Provider(Logger)) { var indexableT = typeof(IIndexable).Assembly .GetTypes() .FirstOrDefault(t => typeof(IIndexable).IsAssignableFrom(t) && t.Name == indexableType); if (indexableT != null) { var generic = provider .GetType() .GetMethod("METHOD_NAME_IN_PROVIDER")) .MakeGenericMethod(indexableT); //This is the same as calling: await provider.METHOD_NAME_IN_PROVIDER(site, searchQuery); return await (Task) generic.Invoke(provider, new object[] { site, searchQuery }); } return null; } } 

希望它可以帮到某人。