1

I'm using webforms and I'm wondering how I can remove the followoing concrete reference to a repository. In the past I've used castle windsor with MVC but I don't think I can use that here?

Code behind:

ICustomerRepository repos;

public Workout_Admin()
    // here is the offending concrete implementation
    : this(new SqlCustomerRepository()) { }

public Workout_Admin(ICustomerRepository repos)
{
    this.repos = repos;
}

UPDATED ---

I've updated the static method as suggeted, as well as adding the additional code to the windsor factory

WindsorContainer container;

public WindsorControllerFactory()
{
    container = new WindsorContainer(
        new XmlInterpreter(new ConfigResource("castle")));

    var controllerTypes =
        from t in Assembly.GetExecutingAssembly().GetTypes()
        where typeof(IController).IsAssignableFrom(t)
        select t;

    foreach (Type t in controllerTypes)
    {
        container.AddComponentLifeStyle(t.FullName, t,
            LifestyleType.Transient);
    }

    CommonServiceLocatorPageHandlerFactory.Container = container;
}

The issue that keeps arriseing is with loading the assembly from the config file. The CommonServiceLocatorPageHandlerFactory is in and assembly called yourfit, folder called factory. And here are the relevant configs

<httpHandlers>
  <add verb="*" path="*.aspx"
    type="YourFit.Factory.CommonServiceLocatorPageHandlerFactory, YourFit"/>
</httpHandlers>
<handlers>
  <remove name="UrlRoutingHandler"/>        
    <add name="CSLPageHandler" verb="*" path="*.aspx"
      type="YourFit.Factory.CommonServiceLocatorPageHandlerFactory, YourFit"/>
</handlers>

and the error is:

Could not load type 'YourFit.Factory.CommonServiceLocatorPageHandlerFactory' from assembly 'YourFit'.

I know I'm most likely being really stupid. Thanks so much for your time on this.

Jeff Sternal
  • 47,787
  • 8
  • 93
  • 120
hoakey
  • 998
  • 3
  • 18
  • 34

1 Answers1

1

You can do this. The ASP.NET compilation engine however needs a default constructor, but you can make it protected. You can inject the dependencies in the other constructor by defining a custom PageHandlerFactory that injects dependencies in the overloaded (public) constructor. Your class would look like this:

public class Workout_Admin : Page
{
    ICustomerRepository repos;

    protected Workout_Admin() { }

    public Workout_Admin(ICustomerRepository repos)
    {
        this.repos = repos;
    }
}

Here is an article that shows you how to do this (for Castle Windsor, just change the code in the GetInstance method to call the Windsor container). Note that you need to run in full trust for this.

UPDATE

You can change the private static object GetInstance(Type type) method that the article describes to the following:

public static IWindsorContainer Container;

private static object GetInstance(Type type)
{
    return Container.Resolve(type);
}

In your application's startup path (where you configure the Castle Windsor container) you than must set the static Container property:

// Create
IWindsorContainer container = ...

// Configure

// Set container to page handler factory
CommonServiceLocatorPageHandlerFactory.Container = container;

I hope this makes sense.

Steven
  • 166,672
  • 24
  • 332
  • 435
  • You also might want to take a look at this SO question: http://stackoverflow.com/questions/293790/how-to-use-castle-windsor-with-asp-net-web-forms. – Steven Jan 06 '11 at 12:37
  • Thanks. I'm currently looking at how to obtain the dll for Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance – hoakey Jan 06 '11 at 14:04
  • In the article he says "I deliberately use the CSL for this, because my Simple Service Locator library depends on that interface. If you're not using the CSL, changing the code to work with your IoC library is can be done by changing a single line, as you will see below". He then doesn't appear to show an example. Therefor, when I run it I get the error " Could not load file or assembly 'CSL' or one of its dependencies". Any ideas? – hoakey Jan 06 '11 at 15:26
  • I think the error message says it all: that assembly can not be found :-). Since you referenced the custom factory from your code, that assembly should be copied to the output, unless you have a secon copy of the `CommonServiceLocatorPageHandlerFactory` in your code. – Steven Jan 06 '11 at 18:30
  • When you say copied to the output, what do you mean? Both the CommonServiceLocatorPageHandlerFactory and the WindsorControllerFactory are in the same assembly "Yourfit". Sorry – hoakey Jan 06 '11 at 19:20
  • With copied I mean that the compiler will copy an assembly for you to the bin directory. If those types are in the same assembly, make sure that assembly is referenced from you application project and double check if the assembly is named 'Yourfit` and the type is really in the namespace 'YourFit.Factory'. That's all I can think of. – Steven Jan 06 '11 at 19:45
  • That's all working now. Thanks Steven you been a massive help! – hoakey Jan 07 '11 at 14:30