Unity - Factory via XML - c#

I am using the Unity framework as IoC container.
My Config looks some like this:
<unity>
<container>
<register type="Namespace1.IFoo, FooAsm"
mapTo="Namespace2.Bar, BarAsm">
</register>
</conainer>
I would like to register a container to use a factory method. How do i achive it using the app.config?
I am looking for something like this:
<unity>
<container>
<register type="Namespace1.IFoo, FooAsm"
factory="Namespace2.Bar, BarAsm"
method="create">
</register>
</conainer>
</unity>
Any suggestsions?

This thread offers a nice response about how to add support of Factory methods for Unity. I fact you have to download this bitbucket source (and change the references to 4.0 framework).
If you now add Generic support for Unity you get a pretty awesome solution that might look like this:
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration"/>
</configSections>
<unity xmlns="schemas.microsoft.com/practices/2010/unity">
<sectionExtension type="Unity.FactoryConfig.FactoryConfigExtension, Unity.FactoryConfig"/>
<alias alias="Factory" type="Namespace1.GenericFactory`1, asm1"/>
<container>
<register type="Namespace1.ITest, asm1">
<factory type="Factory[[Namespace1.ITest, asm1]]" method="Create" />
</register>
</container>
</unity>
</configuration>
Support of generic Factories for unity framework using xml configuration!
Thanks for all comments :)

I don't think there is a built-in way to do this currently. I usually just register the factory itself (Map IMyFactory -to-> MyFactoryImpl) then inject the factory into the classes that need it, and have the classes call the factory.
However, I think you can probably make something call a factory straight from Unity by making an extension for Unity. There are a couple mentioned in the answers to this question: How to create objects using a static factory method?

Related

is there a way to register a factory in Unity's XML configuration?

Is there a way to register a factory in Unity's XML configuration?
Unity should inject some constructor parameters and use the factory in order to instantiate the object.
Here is a Spring .NET based example:
<object id="name" type="Namespace.Factory, Assembly" factory-method="Create">
<constructor-arg name="intParam" value="1" />
<constructor-arg name="objParam" ref="objectName" />
</object>
Many thanks in advance!
Is there a way to register a factory in Unity's XML configuration?
The short answer is no. On the Enterprise Library user voice there is a suggestion to improve XML configuration which include factory methods but it has not been implemented yet.
However, Stack Overflow user Chris Tavares has created a Unity extension on Bitbucket with some support for factory methods in XML configuration.
To use this extension you would use XML configuration along these lines (where FactoryCreated is the type created by the factory):
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<sectionExtension type="Unity.FactoryConfig.FactoryConfigExtension, Unity.FactoryConfig"/>
<alias alias="Factory" type="Namespace.Factory, Assembly"/>
<container>
<register type="NameSpace.FactoryCreated, Assembly">
<factory type="Factory" method="Create"/>
</register>
</container>
</unity>
Unfortunately, this extension only support three types of static factory method signatures:
Create()
Create(IUnityContainer container)
Create(IUnityContainer container, Type type, String name)
Your signature is different but based on this extension you could write your own implementing the rules you require.
Alternatively, it is very easy to specify a factory method using the fluent API at run-time but I guess that you are already aware of this.

configure Unity (3.x) for Generic Repository Pattern on WCF project in app.config

I have a problem to config unity in app.config file, My project is wcf service project and I have used unity on this project well, but I don't know exactly, how to config generic types in app.config, before that I config my unity for MVC web application in UnityConfig.cs class like below and I wanna do that in wcf service project.
What is my wrong?
Works fine in class level:
container.RegisterType(typeof (IRepositoryAsync<>), typeof (Repository<>), new PerRequestLifetimeManager());
container.RegisterType(typeof (IRepository<>), typeof (Repository<>), new PerRequestLifetimeManager());
Not work in app.config:
<register type="IRepository[], FaraGostar.Repository.Pattern.Repositories" mapTo="Repository, FaraGostar.Repository.Pattern">
<lifetime type="singleton" />
</register>
<register type="IRepositoryAsync[], FaraGostar.Repository.Pattern.Repositories" mapTo="Repository, FaraGostar.Repository.Pattern">
<lifetime type="singleton" />
</register>
In my personal view I think, I can not config well []!
See the Generic Types section at the bottom of Unity's Specifying Types in the Configuration File
Short answer the unexpected:
<register type="IRepository`1, FaraGostar.Repository.Pattern.Repositories" mapTo="Repository`1, FaraGostar.Repository.Pattern">

Intellisense and Autocompletion Unity

I am playing with the IoC Container Unity, and according to the documentation, adding this xmlns attribute to the "unity" section must allow Visual Studio doing some Intellisense stuff :
<configuration>
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
</configSections>
[..]
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
[..]
</unity>
</configuration>
Actually, it doesn't work. It seems the resource has been (re?)moved. Do you know the new link ?
The actual xsd file can be found here: https://raw.githubusercontent.com/unitycontainer/configuration/master/src/Unity.Configuration.xsd
It looks like you're talking about this link:
http://msdn.microsoft.com/en-us/library/dn507436(v=pandp.30).aspx

StructureMap, different implementation for different user

We are currently using StructureMap as the IoC container. All was working ok, but now we need to change the defaults in runtime.
What we need is ability to provide IEntityRepository, IEntityService based on a user. Having EntityRepositoryEur, EntityRepositoryRus...
Is there some way how to chnage Instances in runtime based on user setting? What is the best way to do that? Maybe is there some better IoC right now to do that?
I am not familiar with StructureMap but with Unity Application Block (called usually just Unity) you can register more concrete types (services) with single interface. You assign names to these services and at the time of resolution you receive the list of registered services. Then you can choose one based on the user settings.
This is example how to register named services using config file
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
</configSections>
<unity>
<containers>
<container>
<types>
<type name="OutputService1" type="InterfacesLibrary.IOutputService, InterfacesLibrary" mapTo="InputOutputLibrary.ConsoleOutputService, InputOutputLibrary" />
<type name="OutputService2" type="InterfacesLibrary.IOutputService, InterfacesLibrary" mapTo="InputOutputLibrary.MsgBoxOutputService, InputOutputLibrary" />
</types>
</container>
</containers>
</unity>
</configuration>
Or you can do the same thing from code
container.RegisterType<IOutputService, ConsoleOutputService>("OutputService1");
container.RegisterType<IOutputService, MsgBoxOutputService>("OutputService2");
At the time of resolution you resolve one or the other type based on user's requirements
IOutputService outputService;
if (user.LikesConsole == true)
outputService = container.Resolve<IOutputService>("OutputService1");
else
outputService = container.Resolve<IOutputService>("OutputService2");
Have a look at the series of videos on PRISM. The second video is introduction to Unity.

Prevent namespaces of top Config from getting wiped out when loading and configuring other .config in Unity

This is somewhat specific and difficult situation to explain, so bear with me.
I have created a UnityContainerExtension that is responsible for loading and configuring other .config files.
For example, my App.Config file looks like this:
<configuration>
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration, Version=2.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</configSections>
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<assembly name="SomeAssembly" />
<namespace name="SomeAssembly.SomeNameSpace" />
<container>
<extension type="ConfigSectionExtension" />
<extension type="TestExtension" />
</container>
</unity>
</configuration>
My first extension ConfigSectionExtension runs code (following) that loads in and configures the container with another .config file. ex.
var fileMap = new ExeConfigurationFileMap { ExeConfigFilename = "logging.config"};
Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration( fileMap, ConfigurationUserLevel.None );
((UnityConfigurationSection)configuration.GetSection( "unity" )).Configure( Container );
This code runs fine, however the TestExtension extension in my config cannot be resolved after the Container has been configured with the logging.config file.
The specific response is
"The type name or alias TestExtension could not be resolved."
If I remove the code that loads and configures the logging.config file with the container, then both extensions are found. Is there any way to make this work?
This is essentially my approach to the problem of not being able to link together multiple .config files. If someone knows a better way to link .config files together for Unity, I would of course be open to that solution as well.
OK, I think I have an OK solution. For my extension I can just fully qualify the Type and it will work. ie.
<extension type="MediaInjectorUI.ContainerExtensions.ConfigSectionExtension, MediaInjectorUI" />
<extension type="MediaInjectorUI.ContainerExtensions.TestExtension, MediaInjectorUI" />
Maybe not the prettiest thing in the world, but itdoes the job.

Categories