Unity 2.0 and Injection Sample?

May 18, 2010 at 12:40 PM

I am trying to figure out how to use Unity 2.0 to inject the Exception Handling Handler, but the documentation is not all that clear. This is the code I am using:

unityContainer = new UnityContainer();
var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Configure(unityContainer, ConfigurationConstants.UnityContainerName);

unityContainer.AddNewExtension<Interception>();
var exceptionPolicy = unityContainer.Resolve<ExceptionPolicyImpl>("LoggingPolicy");
unityContainer.Configure<Interception>()
    .AddPolicy("ExceptionInterceptionPolicy")
    .AddMatchingRule<MethodSignatureMatchingRule>(new InjectionConstructor("GetAnnouncementsForUser",
        new List<string>{"System.String", "System.Int32", "System.Int32", 
            "SharedContracts.BusinessEntities.AnnouncementSortCriteria",
            "BusinessEntities.SortDirection"}, true))
    .AddCallHandler<ExceptionCallHandler>("LoggingPolicy", new ContainerControlledLifetimeManager());
I have a LoggingPolicy defined in the config as a exceptionPolicy.
However, I get the an error running the code:
[InvalidOperationException: The type ExceptionPolicyImpl has multiple constructors of length 2. Unable to disambiguate.]

Can anyone share a simple sample with me as to how to get this to work? Also, I can't figure out how to set this same sample up via config, rather than code.

Regards,

Thomas

May 19, 2010 at 1:24 AM

You should add the EnterpriseLibraryCoreExtension first before trying to resolve entlib objects.  This extension wires up entlib objects to the container.

unityContainer.AddNewExtension<EnterpriseLibraryCoreExtension>();

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

Aug 19, 2010 at 4:28 PM

I have a similar problem however I'm using the fluent API and a configurator. This is essentially what I have:

_container = new UnityContainer();

var configurator = new UnityContainerConfigurator(_container);
EnterpriseLibraryContainer.ConfigureContainer(configurator, GetConfigurationSource());

private static IConfigurationSource GetConfigurationSource() {

    var assemblyLocation = Assembly.GetExecutingAssembly().Location;            
    string logFilePath = Path.Combine(Path.GetDirectoryName(assemblyLocation), "file.log");

    var builder = new ConfigurationSourceBuilder();
    builder.ConfigureInstrumentation().EnableLogging();
    builder.ConfigureLogging()
        .WithOptions
        .LogToCategoryNamed("General")
        .WithOptions
        .ToSourceLevels(
#if DEBUG
        SourceLevels.Verbose
#else
        SourceLevels.Information
#endif
        )
        .SetAsDefaultCategory()
        .SendTo
        .FlatFile("Log File")
        .FormatWith(new FormatterBuilder()
        .TextFormatterNamed("Textformatter").UsingTemplate(LogTemplate))
        .ToFile(logFilePath);

    builder.ConfigureExceptionHandling()
        .GivenPolicyWithName("Default")
        .ForExceptionType<Exception>()
        .LogToCategory("General")
        .UsingTitle("Enterprise Library Exception Handling")
        .UsingExceptionFormatter<TextExceptionFormatter>()
        .WithPriority(0)
        .WithSeverity(TraceEventType.Error)
        .UsingEventId(100)
        .ThenDoNothing();

    var configSource = new DictionaryConfigurationSource();
    builder.UpdateConfigurationWithReplace(configSource);

    return configSource;
}

I'm getting the same issue when my code hits:

bool rethrow = ExceptionPolicy.HandleException(ex, "Default");
I'm using Unity to resolve my class and I call that within.  Should I be injecting another entlib object into my class's ctor for exception handling? Thanks.

 

 

 

Aug 19, 2010 at 7:26 PM
calvinandhobbes wrote:

I am trying to figure out how to use Unity 2.0 to inject the Exception Handling Handler, but the documentation is not all that clear. This is the code I am using:

unityContainer = new UnityContainer();
var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Configure(unityContainer, ConfigurationConstants.UnityContainerName);

unityContainer.AddNewExtension<Interception>();
var exceptionPolicy = unityContainer.Resolve<ExceptionPolicyImpl>("LoggingPolicy");
unityContainer.Configure<Interception>()
    .AddPolicy("ExceptionInterceptionPolicy")
    .AddMatchingRule<MethodSignatureMatchingRule>(new InjectionConstructor("GetAnnouncementsForUser",
        new List<string>{"System.String", "System.Int32", "System.Int32", 
            "SharedContracts.BusinessEntities.AnnouncementSortCriteria",
            "BusinessEntities.SortDirection"}, true))
    .AddCallHandler<ExceptionCallHandler>("LoggingPolicy", new ContainerControlledLifetimeManager());
I have a LoggingPolicy defined in the config as a exceptionPolicy.
However, I get the an error running the code:
[InvalidOperationException: The type ExceptionPolicyImpl has multiple constructors of length 2. Unable to disambiguate.]

Can anyone share a simple sample with me as to how to get this to work? Also, I can't figure out how to set this same sample up via config, rather than code.

Regards,

Thomas

First off, you shouldn't be resolving ExceptionPolicyImpl directly anyway - that's an internal implementation detail. You're not actually using it in the code as far as I can tell anyway, is this left over from an old version, or a snippet of a larger sample that actually uses this and fails? For general use of the exception block, you should be resolving the ExceptionManager instead, and let it deal with the details of exception policies.

Second, as Sarah said, you need to load the Entlib config into the container by using the EnterpriseLibraryCore extension.

 

Aug 19, 2010 at 7:33 PM
bittondb wrote:

I have a similar problem however I'm using the fluent API and a configurator. This is essentially what I have:

 

_container = new UnityContainer();

var configurator = new UnityContainerConfigurator(_container);
EnterpriseLibraryContainer.ConfigureContainer(configurator, GetConfigurationSource());

... snip code ...

 

I'm getting the same issue when my code hits:

 

bool rethrow = ExceptionPolicy.HandleException(ex, "Default");
I'm using Unity to resolve my class and I call that within.  Should I be injecting another entlib object into my class's ctor for exception handling? Thanks.

 

 

 


The issue is that you're using the static ExceptionPolicy facade, which uses a container internal to Entlib. In addition to configuring the container, you also need to tell Entlib to use it if you're going to use the static facades. That's pretty easy, just do:

EnterpriseLibraryContainer.Current = new UnityServiceLocator(_container);

after you've initialized the container.

Another option would be to get an ExceptionManager instance out of the container as a dependency, and use that instead of the static ExceptionPolicy class. Something like this:

class MyThing {
    private ExceptionManager exm;

    public MyThing(ExceptionManager exm) {
        this.exm = exm;
    }

    public void DoStuff() {
        try {
            StuffThatMightThrow();
        } catch(Exception ex) {
            exm.HandleException(ex, "Default");
        }
    }
}

This is nice because it's all integrated through the container, and it's more easily testable since you can mock out the ExceptionManager. But if you've already got a ton of code using the static facades, we certainly don't expect you to go back and change it all.