I have a feeling that my use of an interface is incorrect. I know that an interface is a contract that the concrete class has to adhere to.
So I will explain the problem I am trying to solve and maybe someone can point me in the right direction.
I am building an app that returns a page for any request, I have three page types, Cms, Product and Category.
All three have to implement the following interface:
public interface IPage
{
PageType PageType { get; set; }
PageContent Content { get; set; }
Meta Meta { get; set; }
}
These properties are requeried whatever the page type.
a page may have extra properties depending on their type, for example a category page could be like so:
public class CategoryPage : IPage
{
public PageType PageType { get; set; }
public PageContent Content { get; set; }
public Meta Meta { get; set; }
public List<Product> Products { get; set; }
}
At the moment I have a page service that will return a page for the requested url.
Based on the PageType it knows what type of page to return.
The problem is that pageService returns an IPage so that it can return any of the page types.
This is a problem as not all my concretes just implement the interface, in the case of a category page it also has a List, which as you would expect I cant access unless I cast to the concrete type.
But is there a way I can return a generic page type and have the receiver know what concrete it is?
I'm sure that how I am doing it that the moment is not the best way and would like some direction and advice as to how I can solve this little problem.
Thanks
Update
I have settled for a cast.
I'm sure there must be a better way of handling a situation where several classes use some base properties but also implement their own. when you get one of these classes from a service you need to know what you have got back so you can work with the relevant properties..
Or maybe what I am trying to do here is just plain wrong and I need to take another approach. I think I will push on with what I have for now but keep thinking about it.
Update 2
I have changed the way I am doing this so I have no need for a cast, I have a PageType enum that I use to identify the type of page that is being worked with.
This coupled with a Ipage that inherits everything needed seems to be a nice enough solution and removes the need for a cast.
You can always check if the object you have a reference to is of a particular type using the is keyword;
That said, if your design requires you to know concrete types, there is most likely something wrong with the design itself. If there are differences in behavior between the classes, implement the differences inside the classes instead of having to cast them to implement it outside of them.