带接口的 Ninject 和存储库模式
这是我现在拥有的接口/类结构:
BaseContentObject 抽象类
public abstract class BaseContentObject : IEquatable<BaseContentObject>
{
...
}
页面具体类
public class Page : BaseContentObject
{
...
}
存储库接口
public interface IContentRepository<T>
{
// common methods for all content types
void Insert(T o);
void Update(T o);
void Delete(string slug);
void Delete(ContentType contentType, string slug);
IEnumerable<T> GetInstances();
T GetInstance(ContentType contentType, string slug);
T GetInstance(string contentType, string slug);
T GetInstance(string slug);
IEnumerable<string> GetSlugsForContentType(int limit = 0, string query = "");
ContentList GetContentItems();
bool IsUniqueSlug(string slug);
string ObjectPersistanceFolder { get; set; }
}
公共接口实现(对于继承 BaseContentObject 类的所有内容类)
public class XmlRepository<T> : IContentRepository<BaseContentObject>
{
public string ObjectPersistanceFolder { get; set; }
public XmlRepository()
{
ObjectPersistanceFolder = Path.Combine(XmlProvider.DataStorePhysicalPath, typeof(T).Name);
if (!Directory.Exists(ObjectPersistanceFolder))
Directory.CreateDirectory(ObjectPersistanceFolder);
}
...
}
global.asax.cs 中的内容特定存储库
public class XmlPagesRepository : XmlRepository<Page> { }
Ninject 规则
Bind<IContentRepository<Page>>().To<XmlPagesRepository>();
给出以下编译时错误:
*The type 'Namespace.XmlPagesRepository' cannot be used as type parameter 'TImplementation' in the generic type or method 'Ninject.Syntax.IBindingToSyntax<T>.To<TImplementation>()'. There is no implicit reference conversion from 'Namespace.XmlPagesRepository' to 'Namespace.IContentRepository<Namespace.Page>'.*
我花了相当多的时间来弄清楚我的类和接口结构来支持我的业务需求。现在我不知道如何克服 Ninject 错误。
我想在 ASP.NET MVC 控制器中使用此结构,如下所示:
public IContentRepository<Page> ContentRepository { get; private set; }
public PageController(IContentRepository<Page> repository)
{
ContentRepository = repository;
}
This is the interfaces/class structure I have now:
BaseContentObject abstract class
public abstract class BaseContentObject : IEquatable<BaseContentObject>
{
...
}
Page concrete class
public class Page : BaseContentObject
{
...
}
Repository interface
public interface IContentRepository<T>
{
// common methods for all content types
void Insert(T o);
void Update(T o);
void Delete(string slug);
void Delete(ContentType contentType, string slug);
IEnumerable<T> GetInstances();
T GetInstance(ContentType contentType, string slug);
T GetInstance(string contentType, string slug);
T GetInstance(string slug);
IEnumerable<string> GetSlugsForContentType(int limit = 0, string query = "");
ContentList GetContentItems();
bool IsUniqueSlug(string slug);
string ObjectPersistanceFolder { get; set; }
}
Common interface implementation (for all content classes that inherit BaseContentObject class)
public class XmlRepository<T> : IContentRepository<BaseContentObject>
{
public string ObjectPersistanceFolder { get; set; }
public XmlRepository()
{
ObjectPersistanceFolder = Path.Combine(XmlProvider.DataStorePhysicalPath, typeof(T).Name);
if (!Directory.Exists(ObjectPersistanceFolder))
Directory.CreateDirectory(ObjectPersistanceFolder);
}
...
}
Content specific repository
public class XmlPagesRepository : XmlRepository<Page> { }
Ninject rule in global.asax.cs
Bind<IContentRepository<Page>>().To<XmlPagesRepository>();
that gives the following compile time error:
*The type 'Namespace.XmlPagesRepository' cannot be used as type parameter 'TImplementation' in the generic type or method 'Ninject.Syntax.IBindingToSyntax<T>.To<TImplementation>()'. There is no implicit reference conversion from 'Namespace.XmlPagesRepository' to 'Namespace.IContentRepository<Namespace.Page>'.*
I've spent quite some time figuring out my classes and interfaces structure to support my business needs. Now I don't know how to get past that Ninject error.
I want to use this structure in ASP.NET MVC controllers like this:
public IContentRepository<Page> ContentRepository { get; private set; }
public PageController(IContentRepository<Page> repository)
{
ContentRepository = repository;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为,如果您使用具体类创建测试用例,您会发现确实无法从
XmlPagesRepository
隐式转换为IContentRepository
。这很难理解,但如果这种转换是可能的,那么我认为使用ToMethod
绑定它:编辑:再看一下,转换是不可能的。
XmlRepository
实现IContentRepository
而不是IContentRepository
。 Page 是 BaseContentObject 并不重要,转换是不可能的。这不会按您的预期工作。Edit2:“实现”是指实现一个接口;您实现一个接口并继承(或扩展)一个类。在不完全理解您要做什么的情况下,这就是我设计存储库的方式:
您现在可以拥有 IPageRepository 的多个实现,并使用 Ninject 绑定适当的实现:
I think if you create a test case using the concrete classes you'll find that indeed you can't implicitly convert from
XmlPagesRepository
toIContentRepository<Page>
. It's hard to follow, but if that conversion is possible then I think bind it usingToMethod
:Edit: In looking at this some more, the conversion isn't possible.
XmlRepository<Page>
implementsIContentRepository<BaseContentObject>
notIContentRepository<Page>
. It doesn't matter that Page is a BaseContentObject, the cast isn't possible. This isn't going to work as you intended.Edit2: "Implement" refers to implementing an interface; you implement an interface and inherit from (or extend) a class. Without fully understanding what you're trying to do, this is how I would design the repositories:
You can now have multiple implementations of IPageRepository and bind the appropriate one using Ninject: