I have a C# application which uses an XML file for configuration.
The configuration file is used for determining if a class is relevant for the current running of the application.
The application monitors several specs of a localhost, each parameter that the application monitors is represented by a class in the project.
What is the correct way to keep track of which classes to monitor and which not?
I'm currently holding a dictionary of the following kind:
Dictionary<string, bool>
Thanks.
I think what you are looking for here is some kind of provider implementation where you want to configure the set of classes which should be created at run time. I don't think there is one correct way to do this. The correct choice would depend largely on the details of your exact use case.
I would go about this by putting together a factory for each type of class you want to create (see factory pattern). You can then configure which factories should be loaded up at runtime using your xml configuration file. You will need to stipulate the assembly and type in the file so you can create the type at run time using reflection. This can be done using the Activator class in C#.
A better approach might be to make use of a dependency injection framework which will do most of the difficult reflection work for you. I am a fan of Ninject but there are plenty of others out there. If you want to stick to purely .net take a look at the Unity Container.
Related
public List<IBusinessObject> RetrieveAllBusinessObjects()
{
var businessObjectType= typeof(IBusinessObject);
List<Type> implementationsOfBusinessObject = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(businessObjectType.IsAssignableFrom).ToList();
return implementationsOfBusinessObject.Select(t =>(IBusinessObject)Activator.CreateInstance(t)).ToList();
}
I was suggested by a user on stack overflow that I should check out dependency injection as a workaround for the above snippit. What would be the benefits of this?
Just a little overview on what the scenario is:
Our database has little to no store procedures so we have begun implementing C# business objects for our more complicated tables. As we are hoping to switch databases some time soon this seems to be the best option. All of the business objects must be loaded using reflection at runtime to help manage them. All of these business objects implement the interface IBusinessObject.
The suggestion to use dependency injection came from this question
EDIT:
The RetrieveAllBusinessObjects method is in a class behind an interface so is directly testable
We use AutoFac if that changes anything. We don't use a separate config file.
-
instead of using the code above, you simply use DI which is configured in the config file of the app but also sometimes you can decorate a property or a parameter in a method which will then be automatically injected in (by the mapping set up either programmatically or via config) when the request is made to access that object or when it is going to be invoked in the method being called in the params.
it also makes it a bit more testable in that you can create different concrete types which implement of an interface, then instead of having to recompile the code, you just flick the mappings by the config file and viola...all works.
DI would do the above without you having to write code to do it so there's less opportunity for you to introduce bugs.
DI gives you many more benefits such as
Making it easier to test individual units of code. Dependencies can be mocked, so you can limit the code being tested
Easy to understand the dependencies within your code. Dependencies generally get injected in certain places, usually the constructor.
Linked to 1/ above, because you should now defined interfaces between your code, when your requirements change & you need to rewrite a component, you can do so with a higher level confidence that it will work with your existing code-base.
There are other benefits that others can probably describe better, but you'll need to evaluate those according to your needs.
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 hope this question makes sense. Basically, I am looking for a set of guidelines, or even a tutorial, that will show how to make an application that can easily add and remove "modules" or "add-ins"
For example, in Microsoft Office, you will commonly see programs that you can download and install and they will just add an extra tab into Microsoft Word (for example) that will implement some new feature.
I have several applications that use basically the same data source, and I'd like to consolidate them and also leave open the possibility of adding more functionality in the future without 1. Requiring a brand new install and 2. Tweaking every piece of my code.
I'm looking for a place to start, mostly.
Thanks in advance.
**
Edit: To elaborate a little more...
The thing I have in mind specifically is an application that accesses a large set of data that is stored in text files and uses some of the data to create a few graphs and maybe some tables. I'd like the ability to add different graphs in the future using the same data. So, you can click Button_A and generate Graph_A, then a few weeks later, you can click Button_B and generate Graph_B.
It would be really nice if I could come up with a way that only required reading the data from the file(s) once, but I know that would involve having to adjust my DataReader class a bit.
One place to start would be to define an interface for your future modules, and build a utility that scans all the dll's therein, looking for classes that implement said interface.
Once you've found supporting classes you can create instances at runtime and add to your application. That's a common idiom in .NET for supporting "plug-ins"
The Activator class is a common way to create instances from a Type at runtime.
http://msdn.microsoft.com/en-us/library/system.activator.aspx
It's hard to give more details without more info in your question. Can you elaborate a bit?
Take a look at the Composite Application Library from Microsoft.
It is aimed at WPF but you could get some ideas from there.
As Adam said, the first thing to do is define the interface for your plugin modules - what can they expect to receive from the container, and what methods must the container be able to call?
As far as the container itself goes, I'm partial to MEF as a location technology; you can create catalogs and re-compose the system when new DLLs are added. I've built a similar system to this for parsing dissimilar files, and the composition capabilities of MEF are awesome for runtime discovery.
I'm interested in creating a desktop application composed of modules such that the source code to those modules is embedded in the application itself, allowing the user to edit the application as they are running it and have the updated modules put into use without restarting the application. Can anyone suggest a good architecture for this?
I'm looking to use Microsoft.Net and C# for this. DLR is not an option.
Thanks!
It's not easy to suggest a good architecture for this in a short posting.
At first, i'd define a contract (an Interface) every module the user writes/modifies must implement. It should contain at least an Execute method.
Then I'd create a Wrapper-Class for these modules which:
loads the source code from a file
The wrapper compiles the file and also makes sure it implements the contract
Contains an indicator of whether the file could be compiled sucessfully
It should also implement the contract, for easy calling and handling
Then I'd have some kind of shell which contains a collection of all the module-wrappers. Any wrapper that sucessfully compiled would then let the Shell call the Execute method of the module interface.
When it comes to compiling and executing code on the fly, this link should provide all the information you need:
http://www.west-wind.com/presentations/dynamicCode/DynamicCode.htm
Well, a dynamic language certainly would have been the best fit...
You can use the types in the System.Reflection.Emit namespace to dynamically create assemblies.
However, it's going to be really painful because you'd need to load those dynamic assemblies into custom AppDomains because otherwise you'll not be able to unload them again.
This again means that you must address marshalling and assembly resolution issues related to cross-AppDomain communication.
What you are probably looking for is the concept of Dependency Injection.
Dependency Injection means that instead of having module X use module Y directly, module X only relies on an interface, and the application tells module X which implementation should use for it, e.g. using module Y.
There are several ways of implementing Dependency Injection. One is to have references to the interfaces in each of your modules, and explicitly let the application configure each of its modules with the right implementation of the interface.
The second wahy of implementing it (and probably the most useful in your case) is by using a central registry. Define all the interfaces that you want to have in your application. These are the interface for which you want to dynamically change the implementation. Then define identifications for these interfaces. These could be strings or integers or GUID's.
Then make a map in your application that maps the identifications to the interfaces, and fill the map with the correct implementations of the interfaces. In a C++ application (I'm not very skilled in C# yet) this could work like this:
std::map<std::string,IInterface> appInterfaces;
appInterfaces["database"] = new OracleDatabaseModule();
appInterfaces["userinterface"] = new VistaStyleUserInterface();
Make all modules go to this central registry whenever they want to use one of the modules. Make sure they don't access the modules directly, but they only pass via the registry. E.g.
MyModule::someMethod()
{
IDatabaseInterface *dbInterface = dynamic_cast<IDatabaseInterface *>(appInterfaces["database"]);
dbInterface->executeQuery(...);
}
If you now want to change the implementation for an interface in the application, you can simply change the entry in the registry, like this:
IInterface *iface = appInterfaces["database"];
if (iface) delete iface;
appInterface["database"] = new SqlServerDatabaseInterface();
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.