How to pass a runtime parameter to a previously registered factory method using a windsor lock?

I have a reporting MVC application that uses Castle Windsor.

When the application starts (in global.asax), all types are registered, and then each subsequent request to the application resolves the corresponding report type, and windsor automatically processes the dependencies.

I need to switch one of the dependent types for the other depending on the parameter passed in the request.

How can i achieve this?

I registered a factory method with windsor to handle the resolution of switchable types, but since it is registered at application startup, how can I pass a parameter to the factory method when the parameter is available only at a later request?

If I try to register a factory for each request, it will work with the first request, but then it will complain about all subsequent requests that the factory has already registered. Unregister a factory after each request does not look like the right thing.

+3
source share
4 answers

When you need to allow types at runtime, the usual solution is to enter factory, which can make the decision at the appropriate time:

public class ReportFactory: IReportFactory {
    IReport CreateReport(bool useDefault) {
        if (useDefault) {
            return new DefaultReport();
        } else {
            return new UnusualReport();
        }
    }
}

Classes that previously required IReportshould require instead IReportFactory.

+2
source

You definitely do not want to change your container based on the request. This is a recipe for disaster.

. HttpContext.Current factory.

IWhatever CreateWhatever() {
     if (HttpContext.Current.Request["parameter"] == "value-for-other-whatever")
       return new FirstWhatever();

     return DefaultWhatever();
}

() factory, , .

public class WhateverFactory : IWhateverFactory {
     public IWhatever GetWhatever(string parameter) {
         if(parameter == "value for other whatever")
            return new OtherWhatever();

         return new DefaultWhatever();
     }
}

factory, factory , .

+2

TypedFactoryFacility factory.

:

  • factory , :

, , "CustomFoo", , .

public interface IFooFactory
{
   IFoo GetFoo(...arguments);
   IFoo GetCustomFoo(..arguments);

   void ReleaseFoo(IFoo foo);
}
  • .
+2

, , , ..

, Windsor :

     container
            .Register(
                    Component.For<IReportFormatter>().ImplementedBy<ReportFormatterWord2003>().Named("word2003"),
                    Component.For<IReportFormatter>().ImplementedBy<ReportFormatterWord2007>().Named("word2007"),
                    Component.For<IReportFormatter>().ImplementedBy<ReportFormatterPdf>().Named("pdf"),
                    Component.For<Func<string, IReportFormatter>>().Instance(container.Resolve<IReportFormatter>),
                    Component.For<Foo>());

Foo

Foo(Func<string, IReportFormatter> reportFormatterFactory)

, Windsor Foo, reportFormatterFactory IReportFormatter, . reesve...

container.Resolve<IReportFormatter>(string)

IReportFormatter, ...

reportFormatterFactory("word2007");

, , factory, factory.

+1

Source: https://habr.com/ru/post/1766043/


All Articles