我必须将 ServiceStack 与 Kephas 集成在一起。我如何让它们与依赖注入一起玩?

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

ServiceStack 使用 Funq 的一种方言(不支持元数据),而 Kephas 使用 MEF/Autofac 之一(需要元数据支持)。我的问题分为两部分:

我以前从未听说过 Kephas,但如果你指的是这个 Kephas Framework on GitHub,它说它使用 ASP.NET 核心,在这种情况下最好让它们都使用 ASP.NET Core 的 IOC,您可以通过在应用程序启动的 ConfigureServices 中注册您的依赖项来完成:

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

或者在 ServiceStack 的最新 v5.6 版本中 Modular Startup 更改您的 ASP.NET Core Startup class 以继承自 ModularStartup,例如:

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

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

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

在这种情况下,您可以 Register ASP.NET Core dependencies in AppHost 通过在 AppHost 的 Configure(IServiceCollection) 中注册它们,在那里它们可以通过 ASP.NET Core 的 IOC + ServiceStack 的 IOC 来解决,例如:

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>();
        //...
    }
}

您可以通过选择使用 Autofac 使 ASP.NET 和 Kephas 使用一个容器。但是,正如@mythz 指出的那样,您需要向 ServiceStack 提供 Autofac IoC 适配器。我认为 ASP.NET 这样做不会有任何问题,因为 Autofac 是 ASP.NET 核心团队的第一个建议。

对于 ASP.NET 核心,如果您需要全部设置,请参考 Kephas.AspNetCore 包并从 StartupBase class 继承。但是,如果您需要控制,请查看 https://github.com/kephas-software/kephas/blob/master/src/Kephas.AspNetCore/StartupBase.cs 并编写您自己的 Startup class。您可能会发现有用的另一个资源是 Kephas.ServiceStack 集成包。

然后,除了注释服务契约和服务实现之外,Kephas 还允许您通过实现 IAppServiceInfoProvider 接口来提供服务定义。这些 class 是自动发现的,所以这几乎就是您必须做的所有事情。

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));
    }
}

请注意,在上面的示例中,IUserAuthRepository 没有提供实现。这表明 Kephas 会自动发现为组合注册的类型中的实现。或者,如果您需要确定性,请随时在注册中使用实例或工厂。