SimpleInjector在反思中的懒惰。

问题描述 投票:0回答:1

我们使用的是 SimpleInjector 作为依赖注入器,我们使用汇编迭代注册所有接口类型。

public static void RegisterInterfaceTypes(this Container container, Assembly assembly)
{
    assembly.GetExportedTypes()
        .Select(t => new {
            Type = t,
            Interface = t.GetInterfaces().FirstOrDefault()
        })
        .ToList()
        .ForEach(t =>
        {
            container.Register(t.Interface, t.Type, Lifestyle.Transient);
        });
}

我们还有懒惰类要注册。我们可以像下面这样一个一个的注册这些类。但是我们想用类似的迭代使用反射来注册所有的懒惰类型。

container.Register(() => new Lazy<ICommonBusiness>(container.GetInstance<CommonBusiness>));
c# .net reflection lazy-loading simple-injector
1个回答
1
投票

你可以利用 ResolveUnregisteredType 延伸方法,进行最后一刻的注册,以解决 Lazy<T> 依赖性。

来源::

public static void AllowResolvingLazyFactories(this Container container)
{
    container.ResolveUnregisteredType += (sender, e) =>
    {
        if (e.UnregisteredServiceType.IsGenericType &&
            e.UnregisteredServiceType.GetGenericTypeDefinition() == typeof(Lazy<>))
        {
            Type serviceType = e.UnregisteredServiceType.GetGenericArguments()[0];

            InstanceProducer registration = container.GetRegistration(serviceType, true);

            Type funcType = typeof(Func<>).MakeGenericType(serviceType);
            Type lazyType = typeof(Lazy<>).MakeGenericType(serviceType);

            var factoryDelegate = Expression.Lambda(funcType, registration.BuildExpression()).Compile();

            var lazyConstructor = (
                from ctor in lazyType.GetConstructors()
                where ctor.GetParameters().Length == 1
                where ctor.GetParameters()[0].ParameterType == funcType
                select ctor)
                .Single();

            var expression = Expression.New(lazyConstructor, Expression.Constant(factoryDelegate));

            var lazyRegistration = registration.Lifestyle.CreateRegistration(
                serviceType: lazyType,
                instanceCreator: Expression.Lambda<Func<object>>(expression).Compile(),
                container: container);

            e.Register(lazyRegistration);
        }
    };
}

使用情况。

container.AllowResolvingLazyFactories();

但请注意 警示 从文件中。

警告: 注册[Lazy<T>]默认是一种设计气味。使用[Lazy<T>]让你的设计更难遵循,让你的系统更难维护和测试。你的系统最多只能有几个这样的[...]。如果你的系统中有许多构造函数依赖于一个[...]。Lazy<T>],请好好看看你的依赖策略。该 下条 详细介绍了为什么[这是]一种设计的味道。

警告:[......]你的组件的构造者应该是简单、可靠和快速的。[...]你的组件的构造者应该是简单、可靠和快速的(正如在 "设计 "中解释的那样)。这个 Mark Seemann的博客文章)。) 这将消除对懒惰初始化的需求。要了解更多关于创建一个可以成功验证的应用程序和容器配置的信息,请阅读 如何验证 容器的配置。

© www.soinside.com 2019 - 2024. All rights reserved.