C# 基于类型约束的Ninject条件泛型绑定
我需要在C# 基于类型约束的Ninject条件泛型绑定,c#,.net,dependency-injection,ninject,C#,.net,Dependency Injection,Ninject,我需要在Ninject上执行一个通用的绑定,但我遇到了一些问题。这些是课程: 公共类BaseBL:IDisposable,IBaseBL 地点:班级 { .... } public类BaseLogAuditoriaBL:BaseBL、IBaseBL 地点:BaseLogAuditoriaEntity { .... } 我希望当我的tenty从BaseLogAuditoriaEntity继承时,它调用BaseLogAuditoriaBL,否则它调用BaseBL 在这种情况下,如何以通用方式配置
Ninject
上执行一个通用的绑定
,但我遇到了一些问题。这些是课程:
公共类BaseBL:IDisposable,IBaseBL
地点:班级
{
....
}
public类BaseLogAuditoriaBL:BaseBL、IBaseBL
地点:BaseLogAuditoriaEntity
{
....
}
我希望当我的tenty
从BaseLogAuditoriaEntity
继承时,它调用BaseLogAuditoriaBL
,否则它调用BaseBL
在这种情况下,如何以通用方式配置我的绑定
如果我把它放在每个类中,它是有效的,但是我需要一个通用的解决方案来解决这个问题
例如:
kernel.Bind(typeof(IBaseBL<>)).To(typeof(BaseBL<>));
kernel.Bind(typeof(IBaseBL<Loja>)).To(typeof(BaseLogAuditoriaBL<>));
kernel.Bind(typeof(IBaseBL)).To(typeof(BaseBL));
Bind(typeof(IBaseBL)).To(typeof(BaseLogAuditoriaBL));
您可以使用When(..)
语法创建满足您需要的条件绑定:
public static class BaseBLBindingExtensions
{
public static IBindingInNamedWithOrOnSyntax<object> WhenEntityMatchesType<TEntityType>(
this IBindingWhenSyntax<object> syntax)
{
return syntax.When(request => DoesEntityMatchType(request, typeof(TEntityType)));
}
private static bool DoesEntityMatchType(IRequest request, Type typeToMatch)
{
return typeToMatch.IsAssignableFrom(request.Service.GenericTypeArguments.Single());
}
}
赞成者:
- 解析速度比使用
约束时快时(…)
- 仅当包含实体的程序集在启动时已知时(应用约定时)才起作用
- 增加启动时间
kernel.Bind(typeof(IBaseBL<>)).To(typeof(BaseBL<>));
kernel.Bind(typeof(IBaseBL<>)).To(typeof(BaseLogAuditoriaBL<>))
.WhenEntityMatchesType<BaseLogAuditoriaEntity>();
using FluentAssertions;
using Ninject;
using Ninject.Activation;
using Ninject.Syntax;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xunit;
namespace NinjectTest.SO40310046
{
public interface IBaseBL<TEntity>
where TEntity : class
{ }
public class BaseBL<TEntity> : IBaseBL<TEntity>
where TEntity : class
{ }
public class SimpleEntity { }
public class BaseLogAuditoriaEntity
{ }
public class ChildBaseLogAuditorialEntity: BaseLogAuditoriaEntity
{ }
public class BaseLogAuditoriaBL<TEntity> : BaseBL<TEntity>, IBaseBL<TEntity>
where TEntity: BaseLogAuditoriaEntity
{ }
public static class BaseBLBindingExtensions
{
public static IBindingInNamedWithOrOnSyntax<object> WhenEntityMatchesType<TEntityType>(this IBindingWhenSyntax<object> syntax)
{
return syntax.When(request => DoesEntityMatchType(request, typeof(TEntityType)));
}
private static bool DoesEntityMatchType(IRequest request, Type typeToMatch)
{
return typeToMatch.IsAssignableFrom(request.Service.GenericTypeArguments.Single());
}
}
public class UnitTest
{
[Fact]
public void Test()
{
var kernel = new StandardKernel();
kernel.Bind(typeof(IBaseBL<>)).To(typeof(BaseBL<>));
kernel.Bind(typeof(IBaseBL<>)).To(typeof(BaseLogAuditoriaBL<>))
.WhenEntityMatchesType<BaseLogAuditoriaEntity>();
kernel.Get<IBaseBL<SimpleEntity>>()
.Should().BeOfType<BaseBL<SimpleEntity>>();
kernel.Get<IBaseBL<BaseLogAuditoriaEntity>>()
.Should().BeOfType<BaseLogAuditoriaBL<BaseLogAuditoriaEntity>>();
kernel.Get<IBaseBL<ChildBaseLogAuditorialEntity>>()
.Should().BeOfType<BaseLogAuditoriaBL<ChildBaseLogAuditorialEntity>>();
}
}
}
kernel.Bind(typeof(IBaseBL<>)).To(typeof(BaseBL<>));
kernel.Bind(typeof(IBaseBL<BaseLogAuditoriaEntity>))
.To(typeof(BaseLogAuditoriaBL<BaseLogAuditoriaEntity>));
kernel.Bind(typeof(IBaseBL<ChildBaseLogAuditoriaEntity>))
.To(typeof(BaseLogAuditoriaBL<ChildBaseLogAuditoriaEntity>));