UnityContainer configured in web.config - c#

I have the following code
var container = new UnityContainer(); //LINE 1
container.RegisterType<ILogUtility,LogUtil>(); //LINE 2
var logger = container.Resolve<Logger>(); //LINE 3
logger.Log(LogType.Warn, "logging from container"); //LINE 4
How do I implement line 2 in web.config such that I will only have to code line 1, 3, and 4 in my code behind? I have searched every where for code example but they are not clear.
Thanks

Take a look at my tutorial
http://netpl.blogspot.com/2011/11/unity-application-block-is-lightweight.html
There's an example XML configuration:
<?xml version="1.0" encoding="utf-8" ?>
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<container>
<register type="ConsoleApplication30.Logic.ICustomService, ConsoleApplication30"
mapTo="ConsoleApplication30.Logic.CustomServiceImpl, ConsoleApplication30" />
</container></unity>
and you load it with
IUnityContainer container = new UnityContainer();
container.LoadConfiguration();

Related

Configuration.SaveAs writes empty config

Getting some odd behavior from Configuration class. This code
class Program
{
static void Main(string[] args)
{
var configFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
var configuration = ConfigurationManager.OpenExeConfiguration(configFile);
var value = configuration.AppSettings.Settings["Supercali"];
if (value != null) Console.WriteLine("Yay, it finally worked!");
else Console.WriteLine("Still broken.");
configuration.SaveAs("ReadConfig.config");
}
}
with this config in AppDomain.CurrentDomain.SetupInformation.ConfigurationFile:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<appSettings>
<add key="Supercali" value="Fragalistic"/>
</appSettings>
</configuration>
writes the following to "ReadConfig.config"
<?xml version="1.0" encoding="utf-8"?>
<configuration>
</configuration>
and prints this
Still broken.
Looking at it in debug view, AppDomain.CurrentDomain.SetupInformation.ConfigurationFile has the correct file, but OpenExeConfiguration seems to create a blank config. The appSettings section is empty. I'm pretty sure this is wrong, but maybe I'm missing something?
Try this:
var configFile = Assembly.GetExecutingAssembly().Location;
var configuration = ConfigurationManager.OpenExeConfiguration(configFile);
var value = configuration.AppSettings.Settings["Supercali"];
if (value != null) Console.WriteLine("Yay, it finally worked!");
else Console.WriteLine("Still broken.");
configuration.SaveAs("ReadConfig.config");
The OpenExeConfiguration expects the path to a DLL/EXE, not to the .config file.

Unity DI Configuration

I am new to Unity DI ,And got stuck with an error while resolving the dependency. The error message says "The current type, Data.Core.Repository.ILogger, is an interface and cannot be constructed. Are you missing a type mapping?"
The config and code as below.
CONFIG
<configSections>
<section name="unity"
type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration"/>
</configSections>
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<assembly name ="BusinessLogic"/>
<assembly name ="Data.Core"/>
<namespace name="Data"/>
<namespace name="Data.Core"/>
<namespace name="Data.Core.Implimentation"/>
<namespace name="Data.Core.Repository"/>
<namespace name="BusinessLogic" />
<typeAliases>
<typeAlias alias="Logger1" type="Data.Core.Implimentation.Logger1,Data.Core.Implimentation" />
<typeAlias alias="Logger2" type="Data.Core.Implimentation.Logger2,Data.Core.Implimentation" />
<typeAlias alias="ILogger" type="Data.Core.Repository.ILogger,Data.Core.Repository" />
</typeAliases>
<container>
<register type="ILogger" mapTo="Logger2" name="Loggerxcs" >
</register>
</container>
Console App (front end)
var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
IUnityContainer container = new UnityContainer().LoadConfiguration(section);
// Resolving Dependancy Error is # here
LoggerBL _logger = container.Resolve<LoggerBL>();
Business Logic
// File Logger
private ILogger _logger;// = new Data.Core.Implimentation.Logger2();
public LoggerBL(ILogger logger)
{
_logger = logger;
}
public string LogToFile()
{
return _logger.LogToFile();
}
}
and Its all fine when I tried to resove the depndancy from c# code , using following
IUnityContainer container = new UnityContainer();
container.RegisterType<ILogger, Logger2>();
but when I moved the same to config I have got the above error. Thanks in advance.
The problem is that in the configuration version you have named your mapping (as "Loggerxcs").
However, your LoggerBL takes an unnamed ILogger as its parameter.
Remove
name="Loggerxcs"
From your configuration and you should be fine.

Update config file

I have a problem with update my ConfigFile in VS2013 with C#.
I have this code:
Configuration configManager = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
KeyValueConfigurationCollection confCollection = configManager.AppSettings.Settings;
confCollection["ID_Uzivatele"].Value = ID_Uzivatele;
configManager.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection(configManager.AppSettings.SectionInformation.Name);
(ID_Uzivatele is a String variable)
and configFile
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="ID_Uzivatele" value="default"/>
</appSettings>
</configuration>
My problem is that(error list):
An unhandled exception of type 'System.NullReferenceException' occurred in KomunikacniAplikace.exe
Anybody has an idea what I am doing wrong?
I would suggest looking at an error case where the setting isn't set: this works for me:
(assuming theres a const for the string so you don't get a typo...)
const string ID_UZIVATELE = "ID_Uzivatele";
Main code:
Configuration configManager = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
KeyValueConfigurationCollection confCollection = configManager.AppSettings.Settings;
if (confCollection.AllKeys.Contains(ID_UZIVATELE)) {
Console.Out.WriteLine("Contains key, modifying : was " + confCollection["ID_Uzivatele"].Value);
confCollection["ID_Uzivatele"].Value = "foo";
} else {
Console.Out.WriteLine("Doesn't contain key, adding");
confCollection.Add(ID_UZIVATELE, "Boom");
}
configManager.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection(configManager.AppSettings.SectionInformation.Name);
If the config file is missing, this will generate it( you might want to check that your App.Config is actually being copied to the output folder (which might be the root cause of your error), but building protection against bad config is always helpful.

Can not read Config File

I have a config file in my project, which I am not able to read in for some reason. Similar code has worked for me in the past. I am not sure what am I doing wrong here. I was wondering if someone would be able to have a look and let me know if I am doing something wrong. Please help...
Here's my code:
KeyValueConfigurationCollection settings;
Configuration config;
ExeConfigurationFileMap configFile = new ExeConfigurationFileMap();
configFile.ExeConfigFilename = "myProject.exe.config";
config = ConfigurationManager.OpenMappedExeConfiguration(configFile, ConfigurationUserLevel.None);
settings = config.AppSettings.Settings;
this.logFilePath = settings["logFilePath"].Value;
this.logFilePath = settings["logFileName"].Value;
Here's my Config File:
<?xml version="1.0"?/>
<configuration>
<add key="logFilePath" value=".//Results//" />
<add key="logFileName" value="Output.xml" />
</configuration>
Thanks in advance,
Harit
harit, try amending your structure to:
<?xml version="1.0"?/>
<configuration>
<appSettings>
<add key="logFilePath" value=".//Results//" />
<add key="logFileName" value="Output.xml" />
<appSettings>
</configuration>
Using the ConfigurationManager creates the requirement for this exact structure to be present. it should work as planned with the above change.
The AppSettings Collection is missing from your configuration. You only have the root-level of configured. But you are requesting in your code.
Your configuration should be
<configuration>
<appSettings>
<add key="logFilePath" value=".//Results//" />
<add key="logFileName" value="Output.xml" />
</appSettings>
</configuration>
Read values from different web.config:
ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = AppDomain.CurrentDomain.BaseDirectory + #"second.config";
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(fileMap,ConfigurationUserLevel.None);
ConfigurationSection mySection = config.GetSection("countoffiles");
if (config.AppSettings.Settings.Count > 0)
{
System.Configuration.KeyValueConfigurationElement customSetting =
config.AppSettings.Settings["countoffiles"];
if (customSetting != null)
{
Response.Write(customSetting.Value);
}
else
{
Console.WriteLine("No countoffiles application string");
}
}

Unity config working backwards

I have the following config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="unity1" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
<section name="unity2" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
</configSections>
<unity1 configSource="unity1.config" />
<unity2 configSource="unity2.config" />
</configuration>
and the following in the unity1 file (unity2 is the same but with 2 instead of 1 in the obvious places.
<?xml version="1.0" encoding="utf-8" ?>
<unity1 xmlns="http://schemas.microsoft.com/practices/2010/unity">
<alias alias="IInjectMe1" type="CommonLib.IInjectMe1, CommonLib"/>
<container name="unity1">
<register type="IInjectMe1" name="Injected1" mapTo="CommonLib.InjectMe1, CommonLib" />
</container>
</unity1>
I have this code in a single class file in an assembly called CommonLib:
public void StartUp()
{
var config1 = (UnityConfigurationSection)ConfigurationManager.GetSection("unity1");
IUnityContainer container = new UnityContainer();
config1.Configure(container, "unity1");
var config2 = (UnityConfigurationSection)ConfigurationManager.GetSection("unity2");
config2.Configure(container, "unity2");
var test1 = container.Resolve<InjectMe1>(); // WHY NOT THE INTERFACE??
var test2 = container.Resolve<InjectMe2>(); // WHY NOT THE INTERFACE??
Console.WriteLine(test1 != null && test2 != null);
}
}
public class InjectMe1 : IInjectMe1 {}
public interface IInjectMe1 {}
public class InjectMe2 : IInjectMe2 {}
public interface IInjectMe2 {}
My question is, above where I've put "WHY NOT THE INTERFACE" why am I having to specify the concrete class instead of the interface? I'm sure it's just late and I can't see the wood for the trees, but I have to specify the concrete type and it creates the correct concrete type. I want to specify the interface and have it resolve.
I want container.Resolve<IInjectMe1>() to work. Note the I for interface.
Edit: If I do the above I get the error:
Test method CommonLib.Tests.UnitTest1.TestMethod1 threw exception:
Microsoft.Practices.Unity.ResolutionFailedException: Resolution of the dependency failed, type = "CommonLib.IInjectMe1", name = "(none)".
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The current type, CommonLib.IInjectMe1, is an interface and cannot be constructed. Are you missing a type mapping?
Don't have the compiler at hand but I suspect you'd have to remove name="Injected1" from the XML.
By creating a named registration, you constrain yourself to named resolving. But apparently, you resolve a default registration.

Categories

Resources