Razzie
Razzie

Reputation: 31222

Pass a value to constructor on instance registration

I have a class CmsService that handles CMS related stuff. For simplicity's sake, say that it has this single constructor:

public CmsService(Site site)
{ .. }

Site is an enum (Site X, Y, or Z) and is used by the service to determine for which site is has to add and retrieve pages, rebuild the sitetree, etcetera.

Obviously, when using this service in Site X, I want to resolve it using Site.SiteX as its constructor parameter:

public PagesController(CmsService cmsService /* how can I pass SiteX here? */)
{ .. }

This is my Castle DI registration:

container.Register(Component.For<CmsService>().LifestylePerWebRequest());

I imagined something like this would be possible:

container.Register(Component.For<CmsService>().ForParameter("site", Site.SiteX).LifestylePerWebRequest());

However, I've been playing with DependsOn and DynamicParameters but I couldn't get it to work. So a concrete example would be much appreciated!

Upvotes: 0

Views: 93

Answers (1)

Patrick Quirk
Patrick Quirk

Reputation: 23747

I'd use the Typed Factory Facility to pass a CmsService factory into the PagesController constructor, and create the CmsService there.

Define the factory interface (no implementation needed):

public interface ICmsServiceFactory
{
    CmsService Create(Site site);
}

Include the facility:

kernel.AddFacility<TypedFactoryFacility>();
kernel.Register(
                Component.For<ICmsServiceFactory>()
                         .AsFactory()
               );

Change your PagesController constructor:

public PagesController(ICmsServiceFactory cmsServiceFactory)
{
    this.cmsService = cmsServiceFactory.Create(Site.Sitex);
}

Note that the CmsService constructor's Site parameter must be named site for the factory to match the arguments.

Upvotes: 1

Related Questions