generics - DryIoC 根据泛型类型参数将参数传递给开放泛型服务的构造函数

标签 generics dryioc

假设我有这项服务和两种策略:

public class SomeService<TEntity> : ISomeService<TEntity>
{
    public SomeService(ICurrentDbContext context, IStrategy<TEntity>? delete = null)
         : base(context, delete ?? new DefaultStrategy<TEntity>())
        {}
}

public class DefaultStrategy<TEntity> : IStrategy<TEntity> {}

public class CustomStrategy<TEntity> : IStrategy<TEntity> {}

我当前的服务注册如下所示:

container.Register(typeof(ISomeService<>), typeof(SomeService<>), Reuse.Transient);

我想要在这里实现的是,如果泛型类型参数 T 实现某个接口(interface)(例如 IFoo),则在 ISomeService 的解析尝试中传递 CustomStrategy。否则,将其保留为默认值 null 的参数。

Ofc 第一个参数在这两种情况下都应自动解析为注册依赖项。

现在不知道如何做到这一点,我应该使用拦截器吗?

最佳答案

您可以这样做(但从您的问题中不清楚为什么您有两种策略 DefaultStrategy<TEntity>CustomStrategy<TEntity> )。

using System.Linq;
using NUnit.Framework;

namespace DryIoc.IssuesTests
{
    [TestFixture]
    public class SO_DryIoC_pass_param_to_constructor_of_open_generic_service_based_on_generic_type_parameter
    {
        [Test]
        public void Test()
        {
            var container = new Container();

            container.Register(typeof(ISomeService<>), typeof(SomeService<>), Reuse.Transient,
                made: Parameters.Of.Details((req, p) => 
                    p.ParameterType.GetGenericDefinitionOrNull() == typeof(IStrategy<>) && 
                    p.ParameterType.GetGenericParamsAndArgs().Any(x => x.IsAssignableTo<IFoo>())
                    ? null                              // the default injection behavior 
                    : ServiceDetails.Of(value: null))   // otherwise return the `null` value
                );

            container.Register<ICurrentDbContext, MyDbContext>();
            container.Register(typeof(IStrategy<>), typeof(DefaultStrategy<>));

            var s1 = container.Resolve<ISomeService<OtherEntity>>();
            Assert.IsNull(((SomeService<OtherEntity>)s1).Delete);

            var s2 = container.Resolve<ISomeService<FooEntity>>();
            Assert.IsNotNull(((SomeService<FooEntity>)s2).Delete);
        }

        public interface ISomeService<TEntity> {}
        public class SomeService<TEntity> : ISomeService<TEntity>
        {
            public readonly IStrategy<TEntity> Delete;
            public SomeService(ICurrentDbContext context, IStrategy<TEntity> delete = null) => Delete = delete;
        }

        public interface IFoo {}
        public class FooEntity : IFoo {}

        public class OtherEntity {}

        public interface IStrategy<TEntity> {}
        public class DefaultStrategy<TEntity> : IStrategy<TEntity> { }
        public class CustomStrategy<TEntity> : IStrategy<TEntity> { }

        public interface ICurrentDbContext {}
        public class MyDbContext : ICurrentDbContext {}
    }
}

关于generics - DryIoC 根据泛型类型参数将参数传递给开放泛型服务的构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65272929/

相关文章:

c# - 该类型不能用作泛型类型或方法 'T' 中的类型参数 'BaseController<T>' 。没有隐式引用

java - 在 Java 中创建一个数组来存储泛型类型

java - 需要有关 java 中复杂结构的建议(DAO 和服务层链接/耦合)

c# - 使用 Linq 表达式和反射获取属性值的通用方法

performance - Xamarin 表单、棱镜表单和 IoC

c# - DryIoC - 在解析时指定一些构造函数参数

generics - 将通用 lambda 放入映射中

c# - DryIoc 用函数解析

c# - 使用 DryIoc 创建具有多个服务注册的单例