Это - структура интерфейсов/класса, которую я имею теперь:
Абстрактный класс BaseContentObject
public abstract class BaseContentObject : IEquatable<BaseContentObject>
{
...
}
Реальный класс страницы
public class Page : BaseContentObject
{
...
}
Интерфейс 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; }
}
Реализация единого интерфейса (для всех классов содержимого, которые наследовали класс 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> { }
Ninject управляют в global.asax.cs
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;
}
Я думаю, что если вы создадите тестовый пример с использованием конкретных классов, вы обнаружите, что действительно нельзя неявно преобразовать из XmlPagesRepository
в IContentRepository
. За этим трудно уследить, но если это преобразование возможно, то я думаю, связать его с помощью ToMethod
:
Bind<IContentRepository<Page>>().ToMethod(x => (IContentRepository<Page>)kernel.Get<XmlPagesRepository>());
Изменить: если посмотреть на это еще раз, преобразование невозможно. XmlRepository
реализует IContentRepository
, а не IContentRepository
. Не имеет значения, что Page является BaseContentObject, приведение невозможно. Это не сработает так, как вы планировали.
Edit2: «Реализовать» относится к реализации интерфейса; вы реализуете интерфейс и наследуете (или расширяете) класс. Не понимая полностью, что вы пытаетесь сделать, вот как я бы спроектировал репозитории:
public interface IPageRepository : IContentRepository<Page>
{
}
public interface XmlPageRepository : IPageRepository
{
// implementation
}
Теперь у вас может быть несколько реализаций IPageRepository и связать соответствующую с помощью Ninject:
Bind<IPageRepository>().To<XmlPageRepository>();