Unity configuration using web.config - c#

I have the following code :
using System.Web.Http;
using Coben.DataAccess.Tests.Constructiv.CentralDB.Contracts.ServiceContracts;
using Coben.Person.DataAccess;
using Constructiv.CentralDB.Contracts.ServiceContracts;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using Unity.WebApi;
namespace CoBen.UI
{
public static class UnityConfig
{
public static void RegisterComponents()
{
var container = new UnityContainer();
container.RegisterInstance<IPersonService>(new PersonServiceMock().Mock);
container.RegisterType<PersonRepository>();
GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
}
}
}
This configures my dependency injection.
But I would like to do the same from my web.config.
i have the following :
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<alias alias="IPersonService" type="Constructiv.CentralDB.Contracts.ServiceContracts.IPersonSercice, Constructiv.CentralDB.Contracts.ServiceContracts" />
<namespace name="Coben.DataAccess.Tests.Constructiv.CentralDB.Contracts.DataContracts.Persons" />
<assembly name="Coben.DataAccess.Tests.Constructiv.CentralDB.Contracts.DataContracts.Persons" />
<container>
<register type="IPersonService" name="special" mapTo="PersonServiceMock().Mock" />
</container>
But when i do it like this I get an error message :
The type name or alias IPersonService could not be resolved. Please check your configuration file and verify this type name.
What am I doing wrong or what am I not seeing ?
Update:
I know get the following error :
The type name or alias Constructiv.CentralDB.Contracts.ServiceContracts.IPersonService, Constructiv.CentralDB.Contracts.ServiceContracts could not be resolved. Please check your configuration file and verify this type name.
My config looks as follows:
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
</configSections>
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<container>
<register type="Constructiv.CentralDB.Contracts.ServiceContracts.IPersonService, Constructiv.CentralDB.Contracts.ServiceContracts"
mapTo="Coben.DataAccess.Tests.Constructiv.CentralDB.Contracts.DataContracts.Persons.PersonServiceMock().Mock, Coben.DataAccess.Tests.Constructiv.CentralDB.Contracts.DataContracts.Persons" />
</container>

You need to configure your instance of the UnityContainer with the settings from the web.config.
UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Configure(_container);

Related

Unity IOC configuration with json

In the app.config, it can look like below and the services and repositories are defined in a different file Unity.config. My question is, is it possible to do below in appsettings.json instead of app.config and Unity.json instead of Unity.config?
app.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="Unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" requirePermission="false" restartOnExternalChanges="true" />
</configSections>
<Unity configSource="Config\Unity.config"/>
<appSettings>
<add key="DateFormat" value="yyyyMMdd"/>
</appSettings>
</configuration>
Unity.config
<Unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<alias alias="IHelpfulRepository" type="Repositories.IHelpfulRepository, Repositories" />
<alias alias="HelpfulRepository" type="Repositories.Implementation.HelpfulRepository, Repositories" />
</Unity>
no it's not possible. there is a work around.
So what I had to do was make my own UnityContainerExtensions class, load an xml file that looks just like an app.config file, get the unity section, and convert that to a UnityConfigurationSection. code below
MyUnityContainerExtensions.cs
public static class MyUnityContainerExtensions
{
public static IUnityContainer LoadXML(this IUnityContainer container, string xmlFilePath = ".\\Config\\Unity.config")
{
XmlDocument doc = new XmlDocument();
doc.Load(xmlFilePath);
var fileMap = new ExeConfigurationFileMap { ExeConfigFilename = xmlFilePath };
Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
UnityConfigurationSection section = (UnityConfigurationSection)configuration.GetSection("unity");
return section.Configure(container, string.Empty);
}
}
Unity.config
<configuration>
<configSections>
<section name="Unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration" requirePermission="false" restartOnExternalChanges="true" />
</configSections>
<Unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<alias alias="IHelpfulRepository" type="Repositories.IHelpfulRepository, Repositories" />
<alias alias="HelpfulRepository" type="Repositories.Implementation.HelpfulRepository, Repositories" />
</Unity>
...
</configuration>
Then where I'm loading the unity configuration, I just call the new extension method.
IUnityContainer container = new UnityContainer().LoadXML();

Unity framework in .net core

I am new to .net core. Need help setting up unity framework. Here is what i tried.
I added reference to System.Configuration.ConfigurationManager .net standard V2.0
Then created app.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<!--In older version, Microsoft.Practices.Unity.Configuration.dll is part of older version (around 3.5.1404). In newer version,
Microsoft.Practices.Unity.Configuration.UnityConfigurationSection class is moved to Unity.Configuration.dll.-->
<!--<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>-->
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration"/>
</configSections>
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<!--Old syntax-->
<!--<typeAliases>
<typeAlias alias="IDBAccess" type="Interfaces.IDataProvider, Interfaces" />
<typeAlias alias="SQLDataAccess" type="SQLDataProvider.DataProvider, SQLDataProvider" />
</typeAliases>-->
<!--New syntax supported in newer versions. So if above syntax does not work then try below one-->
<alias alias="IDBAccess" type="Interfaces.IDataProvider, Interfaces" />
<alias alias="SQLDataAccess" type="SQLDataProvider.DataProvider, SQLDataProvider" />
<alias alias="OracleDataAccess" type="OracleDataProvider.DataProvider, OracleDataProvider" />
<containers>
<container name="DataAccessProvider">
<register type="IDBAccess" mapTo="SQLDataAccess"/>
<register type="IDBAccess" mapTo="SQLDataAccess" name="SQLDataAccess" />
<register type="IDBAccess" mapTo="OracleDataAccess" name="OracleDataAccess" />
</container>
</containers>
</unity>
</configuration>
In class i try reading the configuration , but getting NULL.
UnityConfigurationSection section =
(UnityConfigurationSection)ConfigurationManager.GetSection("unity");
If you mean the Unity DI Container Framework, you don't need to set it up because dotnet core comes with it's own IoC DI container. Also the dotnet core uses appSettings.json config files.
In Startup.cs there should be this method:
public void ConfigureServices(IServiceCollection services)
{
}
And you can configure your dependencies using the services object, like this:
services.AddSingleton<IContract, Contract>();
There are other options on how you can configure your dependencies, I've just presented the Singleton one, but you can go from here.
The easiest way to check this is to start a new project:
dotnet new mvc -n testProj
And check the Startup.cs file, add an interface, an implemenatation to it, then register it into the IServiceCollection instance.
in app.config can you try this
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection"/>
instead of this line
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration"/>
Here is how i finally implemented.
In startup class i configured the dependencies
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddScoped<IRepositoryFactory, RepositoryFactory>();
services.AddScoped<IMapperFactory, MapperFactory>();
services.AddScoped<ITestService, testtService>();
// services.AddScoped<IMapperFactory, MapperFactory>();
}
Here is code to resolve it. using DependencyFactory.Resolve();
public DependencyFactory(IServiceCollection services)
{
_container=services;
}
public static T Resolve<T>()
{
T ret = default(T);
var provider = _container.BuildServiceProvider();
if (provider.GetService<T>() !=null)
{
ret = (T)provider.GetService<T>();
}
return ret;
}

c# Unity container constructor injection of list<childs>

I would like to know how can we inject List of all child objects of an abstract class to a constructor using xml config.
E.g.:
Class Test
{
public Test(List<A> instances) // So this list should have instance of B & C
{
}
}
abstract Class A
{
}
Class B: A
{
}
Class C: A
{
}
Thanks!!!
You can use following config if you change a type of a Test's constructor argument on IList<A>:
<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">
<namespace name="System.Collections.Generic" />
<namespace name="ConsoleApplication1" />
<assembly name="ConsoleApplication1" />
<container>
<register type="A" mapTo="B" name="B" />
<register type="A" mapTo="C" name="C" />
<register type="IList`1[[A]]" mapTo="A[]" />
</container>
</unity>
</configuration>
So the trick is to map IList<A> interface on A[] - see this question for details.

Using unity xml config to register an interface with nested generics

If I have a class that implements a generic interface it works fine to configure it using the unity xml config.
public interface IReader<T> { }
public class Fund { }
public class FundReader : IReader<Fund> { }
and the unity xml:
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<namespace name="System.ComponentModel" />
<namespace name="TestUnityIssue" />
<assembly name="TestUnityIssue" />
<container>
<register type="IReader[Fund]" mapTo="FundReader" />
</container>
</unity>
And this works just using the following code:
var container = new UnityContainer().LoadConfiguration();
var fundReader = container.Resolve<IReader<Fund>>();
However, in some cases there is a wrapper around the type used in the reader. For example, adding the following two classes:
public class Wrapper<T> { }
public class WrappedFundReader : IReader<Wrapper<Fund>> { }
and if I add the following to the unity config:
<register type="IReader[Wrapper[Fund]]" mapTo="WrappedFundReader" />
and then try to resolve it using:
var wrappedReader = container.Resolve<IReader<Wrapper<Fund>>>();
I get the following exception:
InvalidOperationException - The current type,
TestUnityIssue.IReader`1[TestUnityIssue.Wrapper`1[TestUnityIssue.Fund]],
is an interface and cannot be constructed. Are you missing a type
mapping?
I can get around this by configuring it using code instead of xml:
container.RegisterType<IReader<Wrapper<Fund>>, WrappedFundReader>();
or I can create an interface that goes between and use that instead:
public interface IWrappedReader<T> : IReader<Wrapper<T>> { }
public class WrappedFundReader : IWrappedReader<Fund>
and the config would change to:
<register type="IWrappedReader[Fund]" mapTo="WrappedFundReader" />
It will still give me an instance that I can cast to IReader<Wrapper<Fund>>, but it seems like I should be able to make this work with the unity config.
What am I missing to make this work?
(If also tried creating specific aliases and wasn't able to get that to work either)
Aliasing worked for me...
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<alias alias="WrappedFund" type="TestUnityIssue.Wrapper`1[[TestUnityIssue.Fund, TestUnityIssue, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], TestUnityIssue, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<namespace name="TestUnityIssue" />
<assembly name="TestUnityIssue" />
<container>
<register type="IReader[Fund]" mapTo="FundReader" />
<register type="IReader[WrappedFund]" mapTo="WrappedFundReader" />
</container>
</unity>
these both resolved...
var fundReader = container.Resolve<IReader<Fund>>();
var wrappedReader = container.Resolve<IReader<Wrapper<Fund>>>();
and depending on your situation, you may be able to get away with less than the full AssemblyQualifiedName...
<alias alias="WrappedFund" type="TestUnityIssue.Wrapper`1[[TestUnityIssue.Fund, TestUnityIssue]], TestUnityIssue" />

Unity - Inject different classes for the same interface

I have one interface: IFoo
Two classes implementing that interface: FooOne and FooTwo
And two classes ClassOne and ClassTwo receiving an IFoo parameter in the constructor.
How I configure unity so ClassOne receives a FooOne instance and ClassTwo receives a FooTwo using only one container?
I can't do it at runtime so it must be in the config file.
Have a look at the Unity documentation.
For a more readable config file you should define type aliases for IFoo, FooOne, FooTwo, ClassOne and ClassTwo. Then you need to register the mappings from IFoo to your implementations. You need to set a name for the mappings.
For the consumers of IFoo you need to register an InjectionConstructor.
Your config will look something like this:
<?xml version="1.0" encoding="utf-8" ?>
<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">
<alias alias="IFoo" type="UnityConfigFile.IFoo, UnityConfigFile" />
<alias alias="FooOne" type="UnityConfigFile.FooOne, UnityConfigFile" />
<alias alias="FooTwo" type="UnityConfigFile.FooTwo, UnityConfigFile" />
<alias alias="ClassOne" type="UnityConfigFile.ClassOne, UnityConfigFile" />
<alias alias="ClassTwo" type="UnityConfigFile.ClassTwo, UnityConfigFile" />
<container>
<register type="IFoo" name="1" mapTo="FooOne" />
<register type="IFoo" name="2" mapTo="FooTwo" />
<register type="ClassOne" mapTo="ClassOne">
<constructor>
<param name="foo">
<dependency type="IFoo" name="1" />
</param>
</constructor>
</register>
<register type="ClassTwo" mapTo="ClassTwo">
<constructor>
<param name="foo">
<dependency type="IFoo" name="2" />
</param>
</constructor>
</register>
</container>
</unity>
</configuration>
That's the corresponding test that shows how it works.
UnityConfigurationSection config =
(UnityConfigurationSection) ConfigurationManager.GetSection("unity");
IUnityContainer container = new UnityContainer();
container.LoadConfiguration(config);
ClassTwo two = container.Resolve<ClassTwo>();
Assert.IsInstanceOfType(two.Foo, typeof(FooTwo));
Update
At runtime you can do it like this
IUnityContainer container = new UnityContainer();
container.RegisterType<IFoo, FooOne>("One");
container.RegisterType<IFoo, FooTwo>("Two");
container.RegisterType<ClassOne>(new InjectionConstructor(
new ResolvedParameter<IFoo>("One")));
container.RegisterType<ClassTwo>(new InjectionConstructor(
new ResolvedParameter<IFoo>("Two")));
You need to give them registration names to do this:
// Create an instance of a service you want to use. Alternatively, this
// may have been created by another process and passed to your application
LoggingService myLoggingService = new LoggingService();
// Register the existing object instance with the container
container.RegisterInstance<IMyService>("Logging", myLoggingService);
// Register a mapping for another service your application will use
container.RegisterType<IMyService, myDataService>("DataService");
// When required, retrieve an instance of these services
IMyService theDataService = container.Resolve<IMyService>("DataService");
IMyService theLoggingService = container.Resolve<IMyService>("Logging");
Taken from Resolving Instances Of Types Using Unity
I setup in my application like this
Installed Nuget Package Unity version 4.0.1
<package id="Unity" version="4.0.1" targetFramework="net452" />
In my App.config
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
</configSections>
<unity>
<container>
<register type="MyApp.MainWindow, MyApp">
<lifetime type="singleton" />
</register>
<register name="UnityResolver" type="MyApp.Core.Interface.IResolver, MyApp.Core.Interface" mapTo="Avelyn.Core.Container.UnityResolver, Avelyn.Core" />
<register name="NinjectResolver" type="MyApp.Core.Interface.IResolver, MyApp.Core.Interface" mapTo="Avelyn.Core.Container.NinjectResolver, Avelyn.Core" />
</container>
</unity>
In My App.xaml.cs
var _container = new UnityContainer();
_container.LoadConfiguration();
IResolver _unityResolver = _container.Resolve<IResolver>("UnityResolver");
IResolver _ninject = _container.Resolve<IResolver>("NinjectResolver");
MainWindow _win = _container.Resolve<MainWindow>();

Categories

Resources