Search code examples
servicestackkephas

I have to integrate ServiceStack together with Kephas. How do I make them both play together with Dependency Injection?


ServiceStack uses a dialect of Funq (no support for metadata), where Kephas uses one of MEF/Autofac (requires metadata support). My question has two parts:

  • How to make ServiceStack and Kephas use one DI container, if this is possible?

  • Depending on the answer above: how to make ServiceStack services (like IClientCache) available to Kephas components, knowing that such services may not be annotated with [AppServiceContract]?


Solution

  • You can make ASP.NET and Kephas use one container by choosing to work with Autofac. However, as @mythz pointed out, you will need to provide the Autofac IoC Adapter to the ServiceStack. I don't think you will have any problems with ASP.NET in doing so, as Autofac is the first recommendation of the ASP.NET Core team.

    For ASP.NET Core, reference the Kephas.AspNetCore package and inherit from the StartupBase class if you need to be all setup. However, if you need to be in control, have a look at https://github.com/kephas-software/kephas/blob/master/src/Kephas.AspNetCore/StartupBase.cs and write your own Startup class. Another resource that you might find useful is the Kephas.ServiceStack integration package.

    Then, additionally to annotating service contracts and service implementations, Kephas allows you to provide service definitions by implementing the IAppServiceInfoProvider interface. These classes are automatically discovered, so this is pretty much everything you have to do.

    public class ServiceStackAppServiceInfoProvider : IAppServiceInfoProvider
    {
        public IEnumerable<(Type contractType, IAppServiceInfo appServiceInfo)> GetAppServiceInfos(IList<Type> candidateTypes, ICompositionRegistrationContext registrationContext)
        {
            yield return (typeof(IUserAuthRepository),
                             new AppServiceInfo(
                                 typeof(IUserAuthRepository),
                                 AppServiceLifetime.Singleton));
    
            yield return (typeof(ICacheClient),
                             new AppServiceInfo(
                                 typeof(ICacheClient),
                                 ctx => new MemoryCacheClient(),
                                 AppServiceLifetime.Singleton));
        }
    }
    

    Note in the above example that for IUserAuthRepository there is no implementation provided. This indicates Kephas to auto-discover the implementation in the types registered for composition. Alternatively, feel free to use an instance or a factory in the registration, if you need to be deterministic.