Jan
18
2007
Interfaces and generic collections in C#
Posted by admin under
.NET 2.0
When developing ASPCodeHeaderManager I created a servercontrol for managing javascripts etc in an ASP.NET page.
Later I needed a specific servercontrol to be able to interact with the ASPCodeHeaderManager control. However - I wanted to keep the two controls totally unknown of each other - so the solution was to create an Interface. By putting the interface into it's own dll I could create by second server by just referencing the interfaces - and not the actual aspcodeheadermanager control. The good stuff in this is of course that it's possible for me to do upgrades to ASPCodeHeaderManager - and my existing code will keep on working as long as I don't chanhe the interface.
This article on dynamically loading dll in net describes to good things about using interfaces - but lets look at the actual interface and implementation I created for aspcodeheadermanager. The smaller classes was simple enough to create an interface for:
public interface IIncludeScript
{
string Path
{
get;
set;
}
string StaticPathLevel1
{
get;
set;
}
string StaticPathLevel2
{
get;
set;
}
int HighestCompressionLevel
{
get;
set;
}
}
...
As you can see it's possible to use properties in the interface.
The hard part - which I want to talk to you about is collections:
Basically I wanted the interface to look like this:
public interface IHeaderManagerInterface
{
IList<IIncludeScript> IncludeScripts
{
get;
}
IList<IMetaData> MetaData
{
get;
}
...
And yes - the interface is ok - however my implementation of it (inside aspcodeheadermanager which implements the IHeaderManagerInterface) got a little harder:
private List<Stylesheet> m_Stylesheets = new List<Stylesheet>();
[
Category("Data"),
NotifyParentProperty(true),
PersistenceMode(PersistenceMode.InnerProperty),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content)
]
public List<Stylesheet> IncludeStylesheets
{
get
{
return m_Stylesheets;
}
}
IList<ASPCodeHeaderManagerInterface.IStylesheet> ASPCodeHeaderManagerInterface.IHeaderManagerInterface.IncludeStylesheets
{
get
{
return IncludeStylesheets as IList<ASPCodeHeaderManagerInterface.IStylesheet>;
}
}
That was what I was hoping to be able to do. However the IncludeStyleSheet is implemented as a List<Stylesheet> and the interface expects IList<IStylesheet> - although the Stylesheet do implement the IStylesheet interface I always got null as result.
So, my (not so happy with) solution so far:
IList<ASPCodeHeaderManagerInterface.IStylesheet> ASPCodeHeaderManagerInterface.IHeaderManagerInterface.IncludeStylesheets
{
get
{
System.Collections.Generic.List<ASPCodeHeaderManagerInterface.IStylesheet> oList = new List<ASPCodeHeaderManagerInterface.IStylesheet>();
foreach (Stylesheet oScript in IncludeStylesheets)
oList.Add(oScript as ASPCodeHeaderManagerInterface.IStylesheet);
return oList;
}
}
I simply create a new list - List<IStylesheet> and fill it with the Iinterfaces of the Stylesheet objects so to speak.
Does anybody know of a better solution?
The whole solution is available in the ASPCodeHeadermanager project.