Normally, Unity (the DIC) is configured using an standard XML configuration file, such as web.config.
For the purpose of the project, Unity offers great functionality which I would be loving to use. However, since other customers might want to use it, and not all of them will desire to use an XML config file, there is a wish to be able to create adapters, so that the customer can load his/her own configuration the way (s)he wants it.
So, loading the config from a txt, from a custom xml file, from an standard web.config file, or more importantly, from a database schema defined by them, according to their needs. So that all the mappings for the container are on any of those ways.
I was thinking about what was the best way to do this. Probably will end up doing it in a custom way.
Opinions or other tools that compete with Unity that allow this?
Thanks!
The Unity API lets you do everything you can do in the config file. In fact, the config file loader simply reads the instructions and calls the corresponding API.
My first suggestion would be to consider using the API to configure the container in stead of a config file. Second, if you do want to load config from somewhere else, then simply write a reader for whatever format you want, and call the container API based on what you loaded.
There's nothing in the "box" to read config from other sources, but it's easy to write.
One way would be to use reflection to turn type names, stored as strings in the DB, into type instances. Unity can then be configured at application start-up by programatically loading the type mappings into the container.
I don't have VS open at the moment, but I think the syntax would be something like:
var mapFrom = typeof(IMyInterface);
var mapTo = Type.GetType("My.App.MyType"); // load the string from the DB
var container = new UnityContainer();
container.RegisterType(mapFrom, mapTo);
You might also want to look at Microsoft MEF. It doesn't do exactly what you are talking about, but it is more designed around plug-in architectures, and being able to just drop different .dlls into a folder and have the app automatically use them.
Related
We are a group of C#/.NET 4.5 developers working on the same application.
The application has a set of configurations related to each developer machine, like the connection string to the DB, network related settings (proxies, IPs, credentials) and a LOT MORE.
Because the application has grown we are incurring in a lot of environment related configurations like for example:
If this is MyPC then load the connection string for my PC.
If this is the XDeveloperPC then specify proxy’s settings.
Also if new developers leaves or join the group, then the process to update the file becomes a total head ache. Maintaining the file has become very hard and is a possible source of bug and errors.
I was thinking in having specific app.config files related to each developer environment like:
app_MyPC.config
app_XDeveloperPC.config
And when the application builds or executes then specify which one to load as if it where the default app.config of the application. Then, when the application or any class or method refers to a given configuration (like the connection string) is access to this configuration file as if it where accessing to the app.config default file.
I would not want to create a Configuration class that builds immediately when the application starts because then I should have references from every place to this class and the application is quite large, with a bunch of projects and dlls.
I rather prefer to hear some opinions and what do you think should be the best way to achieve this.
Is it possible to achieve this?
How?
Do you know a better approach?
FYI, please note that .NET only loads one config file for the whole application. You could try multiple config files something as like specified here,
Multiple App.Config Files in .NET Class library project
Hope this helps...
You can specify sections of app.config to be loaded from another file. See this answer
However, you might have to customize the above solution, the app.config files and the way configs are organized.
Another approach is to use a custom settings file instead of app.config. This will need some code change to use the config file. This config can either be an XML or a JSON file (JSON is easy to deal with). You can use an inheritance model wherein generic settings come from one file, specific settings come from another file and so on. Also, you can load settings from such file at runtime and change application behavior on the fly.
If you decide to use custom config file, and if you already have lot of code written considering App.config file, you can abstract the app.config calls to a method and let that method deal with where to pull the settings value from. That way you can minimize the code change and keep everything tidy.
Maybe you can use the machine.config file (C:\Windows\Microsoft.NET\Framework\your Framework version\Config\machine.config)
I've always used my own format of configuration files which is XML and then I just deserialise the XML into an object in my project or just read it into an XML document.
This seems alot easier to read and access the information I need.
I've had a look at the ConfigurationManager class this morning and it seems a bit overly complicated just to read a config file.
Is there any argument as to why I should use ConfigurationManager?
It is just a built-in mechanism in .NET which is already implemented for you, so you don't need any extra code (probably except for wrapping it in your own IConfig to separate concerns).
There is a GUI for editing .NET configuration files which sometimes comes in handy.
ASP.NET application, for instance, automatically restart when web.config has been changed, while you would need some custom logic to have the same behaviour with your own config files.
The ConfigurationManager is used internally and you're not obligated in any way to use it, and I used to do what you do. Nowadays it depends, if it is a file a user is supposed to change I might still do my own configuration, otherwise the file is added as an embedded resource and I use the ConfigurationManager to read it, because I don't think there is another way of reading those files. The thing is, use whatever mechanism you feel like, ConfigurationManager provides a bit more encapsulation though and out of the box utils classes.
Here's my problem: I have a computer program (for simulating a vehicle) with a lot of configurable parameters (on the order of 100). The company has traditionally had their own hand-rolled IoC contraption that loads several XML files defining services and parameters. However, lately they want to start the program from a different program (entitled MC) that generates a subset of the parameters specific to each instance.
I've used autofac and ninject2 for other projects, but I'm not seeing quite what I need in them at the moment. I like autofac's XML support. However, I don't really want the MC program to know about all the services of my child program. And I'm not sure the XML merging there is sufficient for my needs.
As one solution, I've considered an IoC container that would easily allow me to fill parameters and properties on services from command line parameters. I assume that would be set up in code as part of registering the services with the container. The container should have an easy way to print and validate said command line parameters. (My parameters are typically real numbers and IP addresses.) Has anyone seen anything like this out in the wild?
I've also been pondering something similar for passing in parameters in XML. Essentially, as part of setting up the IoC you would specify an XML path where that parameter could be obtained. You would then pass XML/filenames to the IoC to fill these. Maybe there is some other parameter format better than XML? It would be helpful if the IoC could spit out a settings schema that would allow me to validate settings files and use that as a standard for other programs that want to configure mine. Thoughts?
Castle windsor had the notion of a IWindsorInstaller - http://stw.castleproject.org/Windsor.Installers.ashx, which is a class for installing the container.
You can implement it however makes sense for your project - xml, command line, whatever, so long as it fills the container as a result.
I think you could use it effectively in the scenario you describe
This may be controversial, but here is what I see
I have a computer program ... with a lot of configurable parameters
You don't need IoC container to store this. Use settings storage: app.config, external XML, resources etc. IoC is for injecting dependencies. Do you have any interfaces in there? Do you have multiple types that implement same interface? Imagine how you would pass 100s parameters into command line, that will be challenging.
Perhaps you can review the current system with XML and see what's the problem with it. Maybe you can use other persisted storage.
I've set up my VSTO Excel add-in to use log4net for logging. Unfortunately I'm (seemingly) not able to make it configure itself from the app.config (which I deliver together with the add-in via ClickOnce).
I have read http://www.darinhiggins.com/?p=13 which lists some ways to get the file name of the app.config and then configure log4net with
log4net.Config.XmlConfigurator.Configure(fileInfo)
However the approaches this blog lists seem very error-prone to me (they "smell bad").
Things like
ConfigurationManager.GetSection
make me believe the .NET framework knows exactly where to get the file and there must be a way to retrieve this information from the framework instead of having to figure it out on my own. However, the XmlConfigurator in turn only accepts a file name, stream or xml node...
(Why I believe it's not working at the moment: I have configured it to use a RollingFileAppender with the file name being H:\Data\Debug.log, but after a GetLogger(...).Debug(...), there is still no Debug.log in place...). I have used the exact same configuration in other places, successfully.
XmlConfigurator.Configure(); uses the app.config file. That should work since the ConfigurationManager seems to be able to read the config file.
If I go to Project -> Myproject Properties -> Settings I can create a settings file for the entire project. However supposed each class requires its own configuration file. Is there a similar way to do this at the class level?
By way of example suppose I have a parent class Car with subclasses Ford and Honda. I want to have a single property YEAR and a single piece of code for reading the YEAR property. I could do this by having two configuration files with the same YEAR property. If I used Ford.YEAR and Honda.YEAR than I would need two separate pieces of code for parsing the data which could get messy for a large number of classes.
It's not really designed for that.
You can use the System.Configuration.ConfigurationSettings classes to open a file explicitly in code to read your settings from. THis will work however the designer will give you no assistance creating your settings files.
Do you have an issue with class wide settings?
Another way that might help you is to create a custom configuration section which you can put in the file. Then you can split each of your classes settings into it's own configuration section. That might suit your purposes?
Configuration data is stored for an executable in its config file (which is a single file, regardless of the number of "settings" files in your project) and is not class-specific. You can set naming conventions for your setting keys configuration options related to a class like ClassName.ConfigName.
You could to create specific sections for your subclasses: How to: Create Custom Configuration Sections Using ConfigurationSection
When you start a .net application, it takes your entry point assembly configuration file and load it up into memory. But just one.
So, if you have a MyApplication.exe which uses a MyLibrary.dll and both have configuration files, just MyApplication.exe.config will be loaded.
You'd have to do it manually, as the others have suggested. However, I'd strongly recommend against this, as I would think you'd have a configuration nightmare to deal with in the end.
As per the other answers, no configuration files are not class specific, you'd be best off creating a class which handles retrieving and setting configuration (a ConfigManager-style interface).
I'd have to ask you though, do you really want configuration per class?
That sounds like a configuration management nightmare scenario. You'd have to entertain scenarios where configuration is either missing or invalid on a per-class basis - and take appropriate steps accordingly.
If your design calls for per-class configuration, perhaps you would be better served storing it in a database or using another medium?
Many of the current IoC containers would allow you to do such a thing through its dependency injection (DI) possibilities. In fact, when XML configuration was all the rage in DI land, you would pretty much get all this out of the box. Today many IoC containers support a programmatic way of setting up dependencies, which you can quite easily hook to whatever XML file you want to provide. Check out this example with the IoC container StructureMap:
IContainer c = new Container();
c.Configure(ce=>
ce.For(typeof(A)).Use(typeof(A)).WithProperty("Test").EqualTo("Hello"));
var a = c.GetInstance<A>();
Debug.Assert(a.Test == "Hello");
By parsing an XML file containing information like targeted type, name of the property, its value, and then calling the above API, you can get what you want.