Using different names to access the same singleton

Feb 17, 2009 at 2:29 AM

I have an interface (say ILogger) that has three concrete implementations: DatabaseLogger, BugTrackerLogger, and FileLogger.

In the production code, I only use DatabaseLogger and BugTrackerLogger. I get the appropriate logger depending on where in the code it is needed by resolving ILogger by name like

container.Resolve<ILogger>("DatabaseLogger")
or
container.Resolve<ILogger>("BugTrackerLogger").

I configure the container in app.config file as seen below and specify the lifetime of  each logger as singleton So far this works fine and I don't have any problems.

 

<

 

unity>
    <
typeAliases>
        <
typeAlias alias="singleton" type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager, Microsoft.Practices.Unity" />
    </
typeAliases>
    <
containers>
        <

 

container>
            <
types>
                <
type type="Logging.ILogger,Common" mapTo="Logging.DatabaseLogger,Common" name="DatabaseLogger">
                    <
lifetime type="singleton"/>
                 </
type>
                <
type type="Logging.ILogger,Common" mapTo="Logging.BugTrackerLogger,Common" name="BugTrackerLogger">
                    <
lifetime type="singleton"/>
                </
type>
            </
types>
        </
container>
    </containers>
</
unity>

 

 

 

Now, what I would like to do is to use only one logger, say FileLogger, during testing for all logging activities. This means that I need to make sure that all those container.Resolve statements with different names return the same singleton instance of FileLogger so that I don't need to change anything in the code. Unfortunately, I could not find a way to configure this via app.config file. At first I thought I could specify an instance in <instances> section. I created my own LoggerTypeConverter that would return an instance of a type of logger as specified as string value. However, I do not know how to plug this instance into the type mapping sections in <types> or use it someplace else in app.config file to indicate to the container to use this instance when resolving ILogger. Is there any way to refer to a particular type mapping with different names like (see the names attributes); 
 
<type type="Logging.ILogger,Common" mapTo="Logging.DatabaseLogger,Common" name="DatabaseLogger, BugTrackerLogger">
    <
lifetime type="singleton"/>
</
type>

I am just getting my hands wet with Unity so I appreciate any pointers, different approaches, and recommendations.

Thank you for time.
  
Mehmet

Mar 13, 2009 at 10:04 PM
Did u solve the problem?
Mar 15, 2009 at 5:16 PM
Not really. One solution that I thought was to provide another mapping for type mapping names. So instead of using the type mapping name defined in <type> element as string literal, the code would use an application settings to get the type mapping name. 

<applicationSettings>
<
UnityApp.Properties.Settings>
<
setting name="DatabaseLoggerTypeAlias" serializeAs="String">
<
value>DatabaseLogger</value>
</
setting>
<
setting name="BugTrackerLoggerTypeAlias" serializeAs="String">
<
value>BugTrackerLogger</value>
</
setting>
</
UnityApp.Properties.Settings>
</
applicationSettings>

This way I can change the above values depending on the build configuration ( test build for example) and the code would get the logger needed for that build configuration.

<applicationSettings>
<
UnityApp.Properties.Settings>
<
setting name="DatabaseLoggerTypeAlias" serializeAs="String">
<
value>FileLogger</value>
</
setting>
<
setting name="BugTrackerLoggerTypeAlias" serializeAs="String">
<
value>FileLogger</value>
</
setting>
</
UnityApp.Properties.Settings>
</
applicationSettings>

However, while a decent solution, I still don't like it and I was hoping to have a way to accomplish this via Unity. 

Mehmet