views:

157

answers:

1

I have been following along in the book Pro ASP.NET MVC Framework by Steven Sanderson. I am trying to rewrite an application to use Unity IoC instead of Castle Windsor IoC. I want the Unity implementation to register all of the controllers like the Windsor one does.

Here is the WindorControllerFactory code:

public class WindsorControllerFactory : DefaultControllerFactory

{

WindsorContainer container;

// The constructor
// 1. Sets up a new IoC container
// 2. Registers all components specified in web.config
// 3. Registers all controller types as components
public WindsorControllerFactory()
{ 
    // Instantiate a container, taking configuration from web.config
    container = new WindsorContainer(
                    new XmlInterpreter(new ConfigResource("castle"))
                );

    // Also register all the controller types as transient
    var controllerTypes = from t in Assembly.GetExecutingAssembly().GetTypes()
                          where typeof(IController).IsAssignableFrom(t)
                          select t;

    foreach (Type t in controllerTypes)
        container.AddComponentWithLifestyle(t.FullName, t, Castle.Core.LifestyleType.Transient);
}

// Constructs the controller instance needed to service each request
protected override IController GetControllerInstance(Type controllerType)
{
    return (IController)container.Resolve(controllerType);
}

}

Here is my feeble attempt at the Unity implementation:

Public Class UnityControllerFactory
Inherits DefaultControllerFactory


Private _container As New UnityContainer()

Public Property Container() As UnityContainer
    Get
        Return _container
    End Get
    Set(ByVal value As UnityContainer)
        _container = value
    End Set
End Property

Public Sub New()
    Dim section As UnityConfigurationSection = DirectCast(ConfigurationManager.GetSection("unity"), UnityConfigurationSection)
    section.Containers("SupportSiteContainer").Configure(_container)
    '_container.RegisterType(GetType(IRepository(Of )), "IRepository", New TransientLifetimeManager(), Nothing)

    Dim controllerTypes = From t In Assembly.GetExecutingAssembly().GetTypes() _
                         Where GetType(IController).IsAssignableFrom(t) _
                         Select t

    For Each t As Type In controllerTypes
        _container.RegisterType(t, t.Name, New TransientLifetimeManager())

        '    ' _container.AddComponentWithLifestyle(t.FullName, t, LifestyleType.Transient)
    Next
End Sub


Public Overloads Function GetControllerInstance(ByVal controllerType As Type) As IController
    If controllerType Is Nothing Then
        Return Nothing
    End If

    Return DirectCast(_container.Resolve(controllerType), IController)
End Function

End Class

Here is my Unity Config:

<unity>
    <typeAliases>
        <!-- Lifetime manager types -->
        <typeAlias alias="singleton" type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager, Microsoft.Practices.Unity"/>
        <typeAlias alias="external" type="Microsoft.Practices.Unity.ExternallyControlledLifetimeManager, Microsoft.Practices.Unity"/>
        <typeAlias alias="transient" type="Microsoft.Practices.Unity.TransientLifetimeManager, Microsoft.Practices.Unity"/>
        <typeAlias alias="perThread" type="Microsoft.Practices.Unity.PerThreadLifetimeManager, Microsoft.Practices.Unity" />
        <!-- Custom object types -->
        <typeAlias alias="IRepository" type="SupportSite.Repository.IRepository`1, SupportSite.Repository"/>
        <typeAlias alias="EFRepository" type="SupportSite.Data.EFRepository`1, SupportSite.Data"/>
        <typeAlias alias="IUnitOfWork" type="SupportSite.Repository.IUnitOfWork, SupportSite.Repository"/>
        <typeAlias alias="EFUnitOfWork" type="SupportSite.Data.EFUnitOfWork, SupportSite.Data"/>
        <typeAlias alias="IUnitOfWorkFactory" type="SupportSite.Repository.IUnitOfWorkFactory, SupportSite.Repository"/>
        <typeAlias alias="EFUnitOfWorkFactory" type="SupportSite.Data.EFUnitOfWorkFactory, SupportSite.Data"/>
    </typeAliases>

    <containers>
      <container name="SupportSiteContainer">
        <types>
            <type type="IRepository" mapTo="EFRepository">
                <lifetime type="transient" />
            </type>

            <type type="IUnitOfWork" mapTo="EFUnitOfWork">
                <lifetime type="transient" />
            </type>

            <type type="IUnitOfWorkFactory" mapTo="EFUnitOfWorkFactory">
                <lifetime type="transient" />
            </type>
        </types>
      </container>
    </containers>

Thanks, Matt

+1  A: 

Try this implementation

pdr
That implementation works like a champ. I unfortunately had tried it earlier, but I didn't override GetControllerInstance and couldn't figure out why it was working. Thanks for the response.Also, in case anyone is curious if you want to register a generic type with unity the code looks like this:'codecontainer.RegisterType(GetType(IRepository(Of )), GetType(EFRepository(Of )))Or'config<typeAlias alias="IRepository" type="SupportSite.Repository.IRepository`1, SupportSite.Repository"/>
Matt Wear