1

我们的框架结构如下:

  • webapi 项目
  • 基本 CQRS 项目
  • Nhibnerate 配置项目

该解决方案使用 Autofac 连接所有类。该 api 将加载所有程序集并在这些程序集中注册所有模块。

大多数模块只是查找所有接口和实现,并且效果很好,每个请求都使用实例。

CQRS 是命令和查询处理程序的一个非常基本的示例。由于将来会有很多并且它们可能具有各种依赖项,我不想手动编写工厂来获取所有处理程序(或在 API 中添加对每个处理程序的引用)。

为了解决上述问题,我有一个命令/查询处理程序工厂,它接受它想要运行的命令或查询。使用反射它找到它的处理程序类型并使用基本 handlerResolver 以便它可以获得处理程序的新实例。为此,我将传递ILifetimeScope给解析器,因此它只在一个地方完成。(我知道引用生命周期范围通常是一种反模式,但我的感觉是,如果我最终得到数百个命令和查询,我最终会得到一个可怕的工厂,它需要所有可能的依赖项,并使用 autofac把它连起来更干净)。

如果每个请求都将所有内容都保留为实例,那么这一切都可以正常工作,则所有类都已解析并且命令和查询将运行。问题是对于每个 API 请求,NHibnernate 配置都会重建,这在我的机器上大约需要 1.5 秒。这意味着几乎每个请求都需要 2 秒才能响应。

我想做的是能够将 NHibnerate 配置和 sessionFactory 注册为单例(因为它不会有任何敏感/用户数据相关信息),以便尽可能少地创建它。还要根据要求保留所有处理程序和其他类,以便它们独立并尽快处理。

连接 web api 的主类:

public static class AutoFacSetup
{
    public static IContainer Create()
    {
        var builder = new ContainerBuilder();

        // this is to insist we use hbm config rather than fluent as there are two implentations of IConfigurationFactory
        builder.RegisterType<OurHbmConfigurationFactory>().SingleInstance();

        var assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToArray();

        // Register your Web API controllers.
        builder.RegisterApiControllers(Assembly.GetExecutingAssembly()).InstancePerRequest();
        builder.RegisterAssemblyModules(assemblies);

        builder.RegisterSelf();
        var container = builder.Build();

        return container;
    }

    public static void RegisterSelf(this ContainerBuilder builder)
    {
        IContainer container = null;
        builder.Register(c => container).AsSelf().SingleInstance();
        builder.RegisterBuildCallback(c => container = c);
    }
}

模块类之一的示例:

public class AutoFacInstallerModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        var assembly = GetType().Assembly;
        builder
            .RegisterAssemblyTypes(assembly)
            .Except<NhibernateDbConnectionFactory>(x => x.SingleInstance())
            .Except<MySessionFactory>(x => x.SingleInstance())
            .AsImplementedInterfaces()
            .InstancePerRequest();
    }
}
4

0 回答 0