1

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]?

Auguste Leroi
  • 215
  • 1
  • 7

2 Answers2

2

I've never heard of Kephas before, but if you're referring to this Kephas Framework on GitHub it says it uses ASP.NET Core in which case it's best if you get them to both use ASP.NET Core's IOC which you can do by either registering your dependencies in ConfigureServices in your App's Startup:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        //...
    }
}

Or alternatively in ServiceStack's latest v5.6 release for Modular Startup change your ASP.NET Core Startup class to inherit from ModularStartup, e.g:

public class Startup : ModularStartup
{
    public Startup(IConfiguration configuration) : base(configuration){}

    public new void ConfigureServices(IServiceCollection services)
    {
        //...
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        //...
    }
}

In which case you'll be able to Register ASP.NET Core dependencies in AppHost by registering them in your AppHost's Configure(IServiceCollection) where they can be resolved through both ASP.NET Core's IOC + ServiceStack's IOC, e.g:

public class AppHost : AppHostBase
{
    public override void Configure(IServiceCollection services)
    {
        services.AddSingleton<IRedisClientsManager>(
            new RedisManagerPool(Configuration.GetConnectionString("redis")));
    }

    public override void Configure(Container container)
    {
        var redisManager = container.Resolve<IRedisClientsManager>();
        //...
    }
}
mythz
  • 141,670
  • 29
  • 246
  • 390
  • Thanks @mythz for clarification, but I don't think it is that easy. Here (https://stackoverflow.com/questions/57636748/how-does-kephas-integrate-with-asp-net-core) it says it needs a DI container supporting metadata, hinting to Autofac. Please correct me if I am wrong, but my understanding is that ServiceStack retrieves the ASP.NET Core service registrations and merges them into its own Funq container, and then will replace the ASP.NET Core's container with its own. – Auguste Leroi Sep 03 '19 at 20:30
  • @AugusteLeroi I'd still recommend using ASP.NET Core's built-in IOC which is going to stand the best chance to work with the rest of ASP.NET Core. Although you can also set ServiceStack to use an [Autofac IOC Adapter](https://docs.servicestack.net/ioc#use-autofac) by passing it Kephas's Autofac container instance in your ServiceStack AppHost.Configure(). – mythz Sep 03 '19 at 20:35
2

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.

ioan
  • 722
  • 4
  • 12
  • 1
    Note that you do not need the Autofac.Extensions.DependencyInjection package if you integrate ASP.NET, Autofac, and Kephas, as this is taken care of in Kephas. – ioan Sep 06 '19 at 20:38
  • I will choose this as an answer as it provides a solution to my second point, too. Thanks @mythz and (@)ioan for providing me with helpful information! – Auguste Leroi Sep 07 '19 at 19:04