Today I came across a cool way of doing dependency injection using ObjectDataSource controls. I am currently involved in a major refactoring project on an application that uses a lot of ObjectDataSources. Thanks to
this blog by Gliff Gray I look to have a way of adding dependency injection without having to change all the ObjectDataSource controls.
Anyone looking for a easy way to do this go and have a look at his blog - in summary you set the ObjectDataSource's DataObjectTypeName to your interface namespace, the TypeName to your interface class and then DI the concrete implementation in the OnObjectCreating method:
One problem I did come across was where I had different variable names in my interface method and my concrete impementation method. In the application I am working on (an eportfolio for University students), there is a service layer interface that defines all the possible functionality of the application, but leaves the actual implementation of the functionality to conrete classes (I think this is a FACADE pattern..). The interface defines a student's identifier as StudentId. Pretty standard stuff really and nice and easy to understand:
/// <summary>
/// Interface for viewAll Comments service. Combines Student and User comments
/// </summary>
public interface IViewCommentService
{
/// <summary>
/// Gets recent comments by StudentId and NumberofDays
/// </summary>
/// <param name="StudentId">Student Identifier</param>
/// <param name="NumberOfDays">Number of days before today to include</param>
/// <returns></returns>
AllCommentsCollection GetRecent(string StudentId, int NumberOfDays);
}
However, my University defines a student's identifier as a PartyNumber. Not exactly intuitive, but is understood by the programmers here. As such, I implemented this method in the concrete class as follows:
/// <summary>
/// Gets recent comments for a student based on NumberOfDays
/// </summary>
/// <param name="PartyNumber">Student PN</param>
/// <param name="NumberOfDays">How many days from now in the past to return</param>
/// <returns></returns>
public AllCommentsCollection GetRecent(string PartyNumber, int NumberOfDays)
{
//removed actual code
}
So, when it came to implementing this method as the select argument of an ObjectDataSource, I was adding a Parameter with the name PartyNumber, not StudentId:
<asp:ObjectDataSource OnObjectCreating="ods_RecentComments_ObjectCreating" ID="ods_RecentComments"
runat="server" SelectMethod="GetRecent" DataObjectTypeName="Eportfolio.IServices"
TypeName="Eportfolio.IServices.IViewCommentService">
<SelectParameters>
<asp:SessionParameter Name="PartyNumber" SessionField="PARTY_NUMBER" Type="String" DefaultValue="1000001" />
<asp:Parameter Name="NumberOfDays" Type="Int32" DefaultValue="20" />
</SelectParameters>
</asp:ObjectDataSource>
This was throwing an error saying there was no method defined that took the parameters PartyNumber and NumberOfDays..... cue some head scratching until I worked out it was looking for the parameters used in the interface method declaration, not the concrete class method declaration. Changing it to StudentId solved the problem:
<asp:SessionParameter Name="StudentId" SessionField="PARTY_NUMBER" Type="String" DefaultValue="1000001" />
This raises the wider point of why I thought it was a good idea to give different names in the method delarations in the first place!