2010-06-29 5 views
1

C'est la structure des interfaces/classe J'ai maintenant:Ninject et modèle référentiel avec des interfaces

BaseContentObject classe abstraite

public abstract class BaseContentObject : IEquatable<BaseContentObject> 
{ 
... 
} 

page classe concrète

public class Page : BaseContentObject 
{ 
... 
} 

Interface Repository

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

mise en œuvre de l'interface commune (pour toutes les classes de contenu héritant classe 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); 
     } 
... 
} 

contenu du référentiel spécifique

public class XmlPagesRepository : XmlRepository<Page> { } 

règle Ninject dans Global.asax.cs

Bind<IContentRepository<Page>>().To<XmlPagesRepository>(); 

qui donne les éléments suivants erreur de compilation:

*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>'.* 

J'ai passé un certain temps à déterminer mes classes et ma structure d'interfaces pour répondre à mes besoins d'affaires. Maintenant, je ne sais pas comment passer cette erreur Ninject.

Je veux utiliser cette structure dans les contrôleurs ASP.NET MVC comme ceci:

public IContentRepository<Page> ContentRepository { get; private set; } 

    public PageController(IContentRepository<Page> repository) 
    { 
     ContentRepository = repository; 
    } 
+0

wouldnt blesser pour donner l'erreur de compilation - cela ouvrira la porte à ceux qui ont touché ce problème et l'ont résolu sans même le considérer comme un gros problème. –

Répondre

2

Je pense que si vous créez un test en utilisant les classes concrètes, vous trouverez que vous pouvez en effet pas convertir implicitement de XmlPagesRepository à IContentRepository<Page>. Il est difficile à suivre, mais si cette conversion est possible, alors je pense que lier l'aide ToMethod:

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

Edit: En regardant ce un peu plus, la conversion est impossible. XmlRepository<Page> implémente IContentRepository<BaseContentObject> pas IContentRepository<Page>. Peu importe que Page soit un BaseContentObject, la distribution n'est pas possible. Cela ne va pas fonctionner comme prévu.

Édition2: «Implémenter» fait référence à l'implémentation d'une interface; vous implémentez une interface et héritez de (ou étendez) une classe. Sans comprendre pleinement ce que vous essayez de faire, voici comment je concevoir les dépôts:

public interface IPageRepository : IContentRepository<Page> 
{ 
} 

public interface XmlPageRepository : IPageRepository 
{ 
    // implementation 
} 

Vous pouvez maintenant avoir plusieurs implémentations de IPageRepository et lier celui approprié à l'aide Ninject:

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

Si vous pouvez comprendre ce que mon cas (sémantiquement) exige, pouvez-vous suggérer une implémentation alternative? – mare

+0

Si vous souhaitez continuer sur le même chemin, vous pouvez simplement créer une implémentation 'IContentRepository '. Je suggère de définir 'IPageRepository' (peut-être en implémentant' IContentRepository ') implémenté par un' XmlPageRepository' l'implémentant. –

+0

J'ai du mal à comprendre ce que vous voulez dire exactement parce que vous utilisez des mots implémentés et implémentés plusieurs fois. Si vous pouvez clarifier ou mieux encore modifier mon code dans votre réponse au niveau que je peux visualiser ce que vous voulez dire, j'accepterai votre réponse. – mare