代码之家  ›  专栏  ›  技术社区  ›  mare

具有接口的Ninject和repository模式

  •  1
  • mare  · 技术社区  · 14 年前

    这是我现在拥有的接口/类结构:

    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);
            }
    ...
    }
    

    特定于内容的存储库

    public class XmlPagesRepository : XmlRepository<Page> { }
    

    global.asax.cs中的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>'.*
    

    我想在ASP.NET MVC控制器中使用以下结构:

        public IContentRepository<Page> ContentRepository { get; private set; }
    
        public PageController(IContentRepository<Page> repository)
        {
            ContentRepository = repository;
        }
    
    1 回复  |  直到 14 年前
        1
  •  2
  •   Jamie Ide    14 年前

    我认为,如果您使用具体的类创建一个测试用例,您将发现实际上您不能隐式地从 XmlPagesRepository IContentRepository<Page> . 很难理解,但如果这种转换是可能的,那么我认为使用 ToMethod :

    Bind<IContentRepository<Page>>().ToMethod(x => (IContentRepository<Page>)kernel.Get<XmlPagesRepository>());
    

    编辑:再看看这个,转换是不可能的。 XmlRepository<Page> 工具 IContentRepository<BaseContentObject> . 页面是BaseContentObject并不重要,强制转换是不可能的。这不是你想要的。

    public interface IPageRepository : IContentRepository<Page>
    {
    }
    
    public interface XmlPageRepository : IPageRepository
    {
        // implementation
    }
    

    现在可以有多个IPageRepository实现,并使用Ninject绑定相应的实现:

    Bind<IPageRepository>().To<XmlPageRepository>();