是否有更简单的方法让Ninject在注入时始终使用最具体的界面?
例如,我有一个通用的存储库接口:
Public Interface IRepository(Of TKey, TEntity As {Class, IEntityKey(Of TKey)})
Sub Save(entity As TEntity)
Sub Delete(entity As TEntity)
End Interface
然后,我为某些实体提供了更具体的界面:
Public Interface ISpecificEntityRepository
Inherits IRepository(Of Integer, SpecificEntity)
Function DoSomethingSpecial() As SpecificEntity
End Interface
Public Class SpecificEntityRepositoryImpl
Inherts RepositoryImpl(of Integer, SpecificEntity)
Implements ISpecificEntityRepository
Overrides Sub Save(entity As TEntity)
' Do something specific here for this entity
End Sub
Function DoSomethingSpecial() As SpecificEntity Implements ISpecificEntityRepository.DoSomethingSpecial
' Do something else
End Function
End Class
此接口继承自通用存储库接口,因此可以始终在其中使用它。
现在在我的Ninject内核中我有绑定:
' The generic repository bindings for all entities
Bind(GetType(IPersistRepository(Of ,))).To(GetType(Repository(Of ,)))
' Specific bindings
Bind(Of IRepository(Of Integer, SpecificEntity)).To(Of SpecificEntityRepositoryImpl)()
Bind(Of ISpecificEntityRepository).To(Of SpecificEntityRepositoryImpl)()
正如您所看到的,特定绑定必须绑定两次。 有没有办法让Ninject始终使用最具体的绑定,所以我需要的是:
' The generic repository bindings for all entities
Bind(GetType(IPersistRepository(Of ,))).To(GetType(Repository(Of ,)))
' Specific bindings
Bind(Of ISpecificEntityRepository).To(Of SpecificEntityRepositoryImpl)()
然后可以看出ISpecificEntityRepository
继承自IRepository
并使用SpecificEntityRepositoryImpl
两者都没有明确地将其绑定两次?
我需要这个的原因是因为我希望我的代码始终使用最具体的实现,无论代码是希望注入通用接口还是特定接口。例如,可以为特定实体中的某些实体覆盖通用接口中的方法,并且我总是希望使用特定版本。
这些应该引用相同的实现:
Dim x as ISpecificEntityRepository ' == SpecificEntityRepositoryImpl
Dim y as IRepository(Of Integer, SpecificEntity) ' == SpecificEntityRepositoryImpl
答案 0 :(得分:0)
两种绑定都是必需的,但您可以使用convention extension来减少工作量。
有些东西(我使用C#语法,因为我不熟悉VB.net,抱歉):
kernel.Bind(x => x
.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom(typeof(IRepository))
.BindWith<RepositoryBindingGenerator>());
public class RepositoryBindingGenerator : IBindingGenerator
{
public IEnumerable<IBindingWhenInNamedWithOrOnSyntax<object>> CreateBindings(Type type, IBindingRoot bindingRoot)
{
// todo: using reflection, get the specific interface type and get T of IRepository<T>
// then create a binding for both like:
yield return bindingRoot.Bind(closedGenericRepositoryInterface).To(type);
yield return bindingRoot.Bind(specificRepositoryInterface).To(type);
}
}