Unity: The type LogWriter cannot be constructed
Asked Answered
Z

6

6

For the following "project" I am getting a very annoying and inexplicable error when resolving Unity for DI.

InvalidOperationException - The type LogWriter cannot be constructed. You must configure the container to supply this value.

?ex.Message; "Resolution of the dependency failed, type = \"WindowsFormsApplication1.Performance\", name = \"(none)\".\r\nException occurred while: while resolving.\r\nException is: InvalidOperationException - The type LogWriter cannot be constructed. You must configure the container to supply this value.\r\n-----------------------------------------------\r\nAt the time of the exception, the container was:\r\n\r\n Resolving WindowsFormsApplication1.Performance,(none)\r\n Resolving parameter \"lw\" of constructor WindowsFormsApplication1.Performance(Microsoft.Practices.EnterpriseLibrary.Logging.LogWriter lw, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ExceptionManager em)\r\n Resolving Microsoft.Practices.EnterpriseLibrary.Logging.LogWriter,(none)\r\n"

?ex.StackTrace; " at Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable1 resolverOverrides) in e:\\Builds\\Unity\\UnityTemp\\Compile\\Unity\\Unity\\Src\\UnityContainer.cs:line 515\r\n at Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, String name, IEnumerable1 resolverOverrides) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\UnityContainer.cs:line 485\r\n at Microsoft.Practices.Unity.UnityContainer.Resolve(Type t, String name, ResolverOverride[] resolverOverrides) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\UnityContainer.cs:line 173\r\n at Microsoft.Practices.Unity.UnityContainerExtensions.Resolve[T](IUnityContainer container, ResolverOverride[] overrides) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\UnityContainerExtensions.cs:line 504\r\n at WindowsFormsApplication1.Form1.OnLoad(EventArgs e) in D:\Devzone\Tasking\WindowsFormsApplication1\Form1.cs:line 33"

In a form:

  protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            try
            {
                IUnityContainer container = new UnityContainer();
                Performance p = container.Resolve<Performance>();
            }
            catch (Exception ex)
            {

            }
        }

Dependency class:

 public class Performance
    {
        public Performance(LogWriter lw, ExceptionManager em)
        {
        }
    }

Configuration File:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
        <section name="exceptionHandling" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Configuration.ExceptionHandlingSettings, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
    </configSections>
    <loggingConfiguration name="" tracingEnabled="true" defaultCategory="General">
        <listeners>
            <add name="Event Log Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FormattedEventLogTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FormattedEventLogTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                source="Enterprise Library Logging" formatter="Text Formatter"
                log="" machineName="." traceOutputOptions="None" />
        </listeners>
        <formatters>
            <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                template="Timestamp: {timestamp}{newline}&#xA;Message: {message}{newline}&#xA;Category: {category}{newline}&#xA;Priority: {priority}{newline}&#xA;EventId: {eventid}{newline}&#xA;Severity: {severity}{newline}&#xA;Title:{title}{newline}&#xA;Machine: {localMachine}{newline}&#xA;App Domain: {localAppDomain}{newline}&#xA;ProcessId: {localProcessId}{newline}&#xA;Process Name: {localProcessName}{newline}&#xA;Thread Name: {threadName}{newline}&#xA;Win32 ThreadId:{win32ThreadId}{newline}&#xA;Extended Properties: {dictionary({key} - {value}{newline})}"
                name="Text Formatter" />
        </formatters>
        <categorySources>
            <add switchValue="All" name="General">
                <listeners>
                    <add name="Event Log Listener" />
                </listeners>
            </add>
            <add switchValue="All" name="Category2" />
        </categorySources>
        <specialSources>
            <allEvents switchValue="All" name="All Events" />
            <notProcessed switchValue="All" name="Unprocessed Category" />
            <errors switchValue="All" name="Logging Errors &amp; Warnings">
                <listeners>
                    <add name="Event Log Listener" />
                </listeners>
            </errors>
        </specialSources>
    </loggingConfiguration>
    <exceptionHandling>
        <exceptionPolicies>
            <add name="Policy">
                <exceptionTypes>
                    <add name="All Exceptions" type="System.Exception, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
                        postHandlingAction="NotifyRethrow" />
                </exceptionTypes>
            </add>
        </exceptionPolicies>
    </exceptionHandling>
</configuration>
Zerk answered 18/10, 2012 at 8:44 Comment(0)
C
11

You need to add the Enterprise Library extension to your container. Without it, the container doesn't read the config file and therefore doesn't know how to create Entlib objects, like the LogWriter.

Chiffchaff answered 18/10, 2012 at 8:54 Comment(4)
For anyone else this is all I needed to do: var container = new UnityContainer().AddNewExtension<EnterpriseLibraryCoreExtension>();Zerk
It took me some time to figure it out, but this answer was very helpful. If someone wants to declare it in a unity.config file this is how it should be done: <extension type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Unity.EnterpriseLibraryCoreExtension, Microsoft.Practices.EnterpriseLibrary.Common" />Certificate
The EnterpriseLibraryCoreExtension has been removed from Enterprise Library 6. You can call the factory constructors and pass a ConfigurationSourceFactory. Details in the migration guide: entlib.codeplex.com/downloads/get/668962Arithmetician
@UriahBlatherwick Thanks! Your comment is worth posting as an answer!Erminna
F
1

Activation error occured while trying to get instance of type LogWriter, key ""

check your config file it must have correct default 'loggingConfiguration' section

Fetiparous answered 27/10, 2015 at 12:22 Comment(0)
H
0

In order for Unity to construct your Performance class, it needs to know how to construct the implementation of ILogWriter.

I cannot see anywhere in your code where you tell Unity what class to create for the ILogWriter interface, so I suspect you may need to add this.

Hbeam answered 18/10, 2012 at 8:49 Comment(4)
He is not using ILogWriter, but LogWriter, which is a concrete class, but he is not providing the dependencies that LogWriter requires in its constructor.Itol
This is DI right, so Im asking for a LogWriter (a concrete implementation of ILogWriter) in the constructor of the Performance class?Zerk
Yep, indeed you are, I must have imagined that. So is there a parameterless constructor for LogWriter?Hbeam
No Chris is onto it. Im sure there are a ton of ways of doing it, but his is the simple way I remember. Unity "just knows" about it's Ent Libs constructors if you feed it an EntLib extensions which I guess is some kind of mapping?Zerk
I
0

LogWriter does not have an empty constructor or a constructor with all concrete types parameters: LogWriter Constructor.

So Unity fails in building it and as it says, it will need your help by configuring the container to provide an implementation.

As a confirmation, ExceptionManager will probably be resolved ok, since it has only one constructor, parameterless as well :)

Itol answered 18/10, 2012 at 8:51 Comment(1)
Hmm what you;ve said makes sense but I dont remember ever concerning myself with constructors on types from Ent Lib blocks.Zerk
B
0

Try this:

protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            try
            {
                IUnityContainer container = new UnityContainer();
                container.RegisterType<ILogWriter, LogWriter>();
                container.RegisterType<ExceptionManager>();
                container.RegisterType<Performance>(new InjectionConstructor(typeof(ILogWriter), typeof(ExceptionManager));                    
                Performance p = container.Resolve<Performance>();
            }
            catch (Exception ex)
            {

            }
        }
Bumgarner answered 18/10, 2012 at 8:53 Comment(0)
W
0

I was getting this issue and simply a PC restart made this issue "go away" .. The PC did an MS update as part of restart. Not much of a solution, but maybe useful comment to someone.

Wilburnwilburt answered 11/10, 2023 at 6:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.