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
Related
I would like to make an app.config that looks like
<configuration>
<SQLconneciton>
<add key=name/>
<add key= otherStuff/>
</SQLconnection>
<PacConnection>
<add key=name/>
<add key= otherStuff/>
</PacConnection>
</configuration>
I've read many examples where people make ONE custom section and add stuff, I need to allow the user to add multiple sections, read, delete. I don't really need fancy elements, just simple add and key values. Is section groups worth using or is there something easy I'm missing?
Sure - there's really nothing stopping you from creating as many custom config sections as you liked!
Try something like this:
<?xml version="1.0"?>
<configuration>
<!-- define the config sections (and possibly section groups) you want in your config file -->
<configSections>
<section name="SqlConnection" type="System.Configuration.NameValueSectionHandler"/>
<section name="PacConnection" type="System.Configuration.NameValueSectionHandler"/>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
<!-- "implement" those config sections as defined above -->
<SqlConnection>
<add key="abc" value="123" />
</SqlConnection>
<PacConnection>
<add key="abc" value="234" />
</PacConnection>
</configuration>
The System.Configuration.NameValueSectionHandler is the default type to use for a config section that contains <add key="...." value="....." /> entries (like <appSettings>).
To get the values, just use something like this:
NameValueCollection sqlConnConfig = ConfigurationManager.GetSection("SqlConnection") as NameValueCollection;
string valueForAbc = sqlConnConfig["abc"];
And you can absolutely mix and match existing section handler types as defined by .NET as well as your own custom config sections, if you've defined some of those yourself - just use whatever you need!
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.
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.
I'm creating a Custom tag in my web.config. I first wrote the following entry under the configSections section.
<section name="castle"
type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler,
Castle.Windsor" />
But, when I try to create a castle node inside the configuration node as below
<castle>
<components>
</components>
</castle>
I get the following error message:"*Could not find schema information for the element '**castle'*." "***Could not find schema information for the element '**components'***."
Am I missing something? I can't find why. And, if I run the application anyway, I get the following error "Could not find section 'Castle' in the configuration file associated with this domain."
Ps.// The sample comes from "Pro ASP.NET MVC Framework"/Steven Sanderson/APress ISBN-13 (pbk): 978-1-4302-1007-8" on page 99.
Thank you for the help
============================================================
Since I believe to have done exactly what's said in the book and did not succed, I ask the same question in different terms. How do I add a new node using the above information?
=============================================================================
Thank you. I did what you said and do not have the two warnings. However, I've go a big new warning:
"The element 'configuration' in namespace 'MyWindsorSchema' has invalid child element 'configSections' in namespace 'MyWindsorSchema'. List of possible elements expected: 'include, properties, facilities, components' in namespace 'MyWindsorSchema'."
What you get is not an error that will prevent you from running your application. It is just a warning that Visual Studio emits because it does not know the castle node in a config file. You could use a schema to enable intellisense. Download the Castle Windsor Schema file and take a look at the readme.txt inside. It tells you to put windsor.xsd somewhere on your hard drive and then reference it in the config file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns="MyWindsorSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="MyWindsorSchema file://S:\Common\Windsor\windsor.xsd">
<configSections>
<section name="castle" type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor" />
</configSections>
<castle>
<components>
</components>
</castle>
</configuration>
I'm currently getting an error trying to resolve my IDataAccess class.
The value of the property 'type' cannot be parsed. The error is: Could not load file or assembly 'TestProject' or one of its dependencies. The system cannot find the file specified.
(C:\Source\TestIoC\src\TestIoC\TestProject\bin\Debug\TestProject.vshost.exe.config line 14)
This is inside a WPF Application project.
What is the correct syntax to refer to the Assembly you are currently in? is there a way to do this? I know in a larger solution I would be pulling Types from seperate assemblies so this might not be an issue. But what is the right way to do this for a small self-contained test project. Note: I'm only interested in doing the XML config at this time, not the C# (in code) config.
UPDATE: see all comments
My XML config:
<configuration>
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
</configSections>
<unity>
<typeAliases>
<!-- Lifetime manager types -->
<typeAlias alias="singleton" type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager, Microsoft.Practices.Unity" />
<typeAlias alias="external" type="Microsoft.Practices.Unity.ExternallyControlledLifetimeManager, Microsoft.Practices.Unity" />
<typeAlias alias="IDataAccess" type="TestProject.IDataAccess, TestProject" />
<typeAlias alias="DataAccess" type="TestProject.DataAccess, TestProject" />
</typeAliases>
<containers>
<container name="Services">
<types>
<type type="IDataAccess" mapTo="DataAccess" />
</types>
</container>
</containers>
</unity>
</configuration>
In unity 5.7
The section line should be like this
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Unity.Configuration" />
This looks fine. Are you sure your assembly name is correct? Check the project preferences to make sure the name of your assembly is correct:
Right click your project and click Properties
Click on the Application tab on the left
Look at the value of the "Assembly Name" field.
Sometimes if you've renamed your project, this field will still be the old value.
It's possible that this is not the issue at all, but it is the simplest thing to check. If you find that this is not the issue, reply to this and I'll post any other ideas I have.
Also, you might consider posting your sample as a .zip file so we can take a look at it.
I just had the same issue. this works for me :
Turn "Copy local" to true in the properties of Microsoft.Practices.Unity.
You should also add a reference to Microsoft.Practices.ObjectBuilder2 (Microsoft.Practices.Unity depends of it)