One-stop service fabric

I am looking to have a general service like ie -

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

However, the structure of the service does not allow the use of common classes or common methods. I also tried something like

 public interface INinjaService : IService, IFooService<SuperNinja> { } 

but it does not display inherited interfaces by specifying

The service type "Omni.Fabric.Services.NinjaService" does not implement any service interfaces. A service interface is one that derives from the type "Microsoft.ServiceFabric.Services.Remoting.IService".

I can not find the generic link in the technical documentation or stackoverflow documentation. Either it's still too new, or maybe I'm heading the wrong way. Did anyone manage to implement such a template? It can be done? Should this be done?

NinjaService on request

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

Consumption code (called by Owin WebApi

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

Services in the Fabric service can implement common interfaces:

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

This is normal.

What is not supported is the common interfaces for remote procedure call (RPC). This refers to the Remote Access communication stack that you have with the IService and listening device for communication.

So, in your case, no, generics are not yet supported. But this is a limitation of this particular intercom package, not the services as a whole, and, of course, you can use any exchange stack you want .

+3
source

It may be late for an answer, but it may help someone. I solved this by making sure that every interface implemented in the service class inherits from IService. In this case, you will have the following:

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

Try it, it should work. If you need to implement several different interfaces in your service, I tried the following options:

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

or

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

Hope this helps.

+2
source

Service fabric uses these extension methods to remove non-service type interfaces

 internal static class ServiceTypeExtensions { public static Type[] GetServiceInterfaces(this Type serviceType) { List<Type> typeList = new List<Type>(((IEnumerable<Type>)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<Type> typeList = new List<Type>(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; } } 

and checks the result

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

So I found a workaround for this case

 public interface IServiceWrapper : IService { } public interface INinjaService : IServiceWrapper, IFooService<SuperNinja> { } 

UPDATED

After some investigation, I found that the proxy checks that all interface parents must be IService, which means

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

So, you need to make IFooService<T> obtained from IService , which is not supported at the moment.

So generics are not supported :(

0
source

All Articles