views:

126

answers:

3

I currently have a library of UserControls which I use in a lot of our web applications. I would like to update these controls so that I can use IOC to help seperate the logic.

So I would have something similar to the following on the web page itself:

<prefix:ControlName ID="myControl" runat="server" property="value1" />

And the control would have a constructor similar to:

public ControlName (IControlLogic logic)

Then ideally the IOC container would handle the injection. Can this be done? If so what libraries offer this? If you have any links that you know of that discuss this they would be great thanks.

Thanks in advance

+1  A: 

Yes you can, I would suggest you look at spring.net

http://www.springframework.net/doc-latest/reference/html/springair.html

I am not sure if you want to keep the usercontrol idea that you are suggesting.

Personally I use spring.net and nHibernate together (although avoiding the Hibernate Templates currently provided) which is working fantastically with .net MVC beta stuff.

Using Spring.net to handle nHibernate slightly reduces the config entries, and MVC doesn't use the context xmls you would would need (springair is a good example).

best of luck

Unfortunately we have a quite a few usercontrols in this library so it can't just be ported across to MVC quickly. And injecting into a user control with a constructor doesn't work but I have worked out I inject into fields the relevant information / behaviour.
John_
+2  A: 

Unfortunatley ASP.NET does not seem to support any easy factory creation pattern for controls. However, in 3.5 you are given very fine grained control over the actual code that the ASP.NET runtime generates for your .aspx file.

Simply apply [ControlBuilder(...)] attributes to all the controls that you want constructed by your container. Subclass ControlBuilder and override ProcessGeneratedCode to replace the constructor with a call to your container.

Here's a simple example:

public class ServiceProviderBuilder : ControlBuilder
{
    public override void ProcessGeneratedCode(System.CodeDom.CodeCompileUnit codeCompileUnit, System.CodeDom.CodeTypeDeclaration baseType, System.CodeDom.CodeTypeDeclaration derivedType, System.CodeDom.CodeMemberMethod buildMethod, System.CodeDom.CodeMemberMethod dataBindingMethod)
    {
        // search for the constructor
        foreach (CodeStatement s in buildMethod.Statements)
        {
            var assign = s as CodeAssignStatement;
            if (null != assign)
            {
                var constructor = assign.Right as CodeObjectCreateExpression;
                if (null != constructor)
                {
                    // replace with custom object creation logic
                    assign.Right = new CodeSnippetExpression("("+ ControlType.FullName + ")MyContainer.Resolve<" + ControlType.BaseType.FullName + ">()");
                    break;
                }
            }
        }
        base.ProcessGeneratedCode(codeCompileUnit, baseType, derivedType, buildMethod, dataBindingMethod);
    }
}    

[ControlBuilder(typeof(ServiceProviderBuilder))]
public partial class WebUserControl1 : System.Web.UI.UserControl
{
    public WebUserControl1()
    {

    }

    protected void Page_Load(object sender, EventArgs e)
    {

    }
}
nicknerdy
A: 

Unfortunately there is no one answer to this question, many IOC containers contain some implementation of injecting control properties but there is no way (currently) of actually creating a control without a parameterless constructor.

John_