5

I am trying to implement DI in a webforms project, so I installed the Unity.WebForms dlls in my UI layer. As soon as I did an App_Start folder was created for me with a UnityWebFormsStart class file. Inside this file there is a method RegisterDependencies which asks to be edited.

What is the next step after registering the dependencies? Is there something I need to add in the Global.asax class file? And how and where do I resolve a type inside a webform? Do I decorate that with any attributes?

1 Answers1

11

The Unity.WebForms dll and NuGet package does a few things for you in the background. It will ensure that a child container is started at the begin of each new web request and disposed at the end of each request. This allows you to register components with a 'per web request' lifestyle (using the HierarchicalLifetimeManager in Unity), which is useful for components such as O/RM unit of works such as Entity Framework's DbContext.

The other thing that the package ensures is that the given HttpHandler (usually your Page) and all its child controls are Built up. The BuildUp method is the way to initialize components that are not created by the container itself.

So the idea is to use property injection in your page classes and controls, but solely use constructor injection in ALL other components in your application. Constructor injection is the preferred mechanism for doing dependency injection, but constructor injection is unfortunately not possible in ASP.NET Page and Control classes.

So your page could look like this:

public class CancelOrderPage : Page
{
    [Dependency]
    public ICommandHandler<CancelOrder> CancelOrderHandler { get; set; }

    void CancelButton_Click(object sender, EventArgs e) {
        this.CancelOrderHandler.Handle(new CancelOrder {
            OrderId = Guid.Parse(this.OrderIdHiddenField.Value)
        });
    }
}

For the rest of your application, use constructor injection:

public class CancelOrderHandler : ICommandHandler<CancelOrder>
{
    private readonly IAuthorizedRepository<Order> orderRepository;
    private readonly IEventPublisher eventPublisher;

    public CancelOrderHandler(IAuthorizedRepository<Order> orderRepository,
        IEventPublisher eventPublisher) {
        this.orderRepository = orderRepository;
        this.eventPublisher = eventPublisher;
    }

    public void Handle(CancelOrder command) {
        // some implementation
    }
}

In the RegisterDependencies you will have to register your dependencies. You can do this manually:

container.RegisterType<ICommandHandler<CancelOrder>, CancelOrderHandler>();
container.RegisterType<IEventPublisher, InProcessPublisher>();
container.RegisterType(
    typeof(AuthorizedRepository<>), 
    typeof(DbContextRepo<>));

Or you can use batch-registration.

Steven
  • 166,672
  • 24
  • 332
  • 435
  • 1
    Why do we need Unity.WebForms or Unity.MVC? Are these layers on top of MS.Entlib.P&P? Actually we can only use Unity of the MS.Entlib, right? And build up our own DI in webforms, mvc, web api .... – Legends Apr 02 '15 at 11:53
  • 1
    I wrote the *Unity.WebForms* NuGet package and the answer that Steven provided above is absolutely correct. For more information about how this works, you can read through the Wiki at the project website. **Note** - I am currently adding the ability to specify namespaces that you wish to exclude from dependency injection scanning based on some issues with 3rd party libraries. I have some free time coming up and hope to have that tested and checked in soon. – KyKo Feb 16 '15 at 01:06
  • @legends These two projects help configure the Unity that ships with P&P's Enterprise Library code. – David Keaveny Feb 22 '16 at 03:49
  • Unity.WebForms in particular is long overdue, and my big thanks to @KyKo for getting it out there. The sample code on the MSDN application is pretty awful in its implementation. – David Keaveny Feb 22 '16 at 03:50
  • 1
    Since .NET Framework 4.7.2 it's now possible to use constructor injection in ASP.NET Web Forms for Pages and Controls. See here: https://devblogs.microsoft.com/aspnet/use-dependency-injection-in-webforms-application/ – Dai Jul 20 '19 at 06:27