I'm developing a Class Library / API and I need to store some global parameters that will be used by some classes. I thought about two main ways to do so (ignoring configuration files which I'd prefer not using in this case):
1) Specifying the parameters in a static class, like this:
// Stores and validates settings
ApiConfiguration.SetConfiguration("some values or class here");
var methods1 = new MyFirstApiMethods();
methods1.DoStuff(); // Internally uses static ApiConfiguration.
var methods2 = new MySecondApiMethods();
methods2.DoOtherStuff(); // Internally uses static ApiConfiguration.
2) Creating an instance of the configuration class and pass it to the classes, like this:
// Create an instance of the configuration class
var config = new ApiConfiguration();
config.ServerName = "some-server-name";
var methods1 = new MyFirstApiMethods(config);
methods1.DoStuff(); // Uses the supplied ApiConfiguration instance.
var methods2 = new MySecondApiMethods(config);
methods2.DoOtherStuff(); // Uses the supplied ApiConfiguration instance.
The fist option feels more natural for me, but I can think of some possible downsides (if the config is set in two places with different values, for example).
I want to know the possible downsides of each implementation and what is the most common way to do this in known projects of this nature.
I'd say #1 is the most common. I know you said that you didn't want to use configuration files, but if you look at how .NET uses app.config I think you will see that a similar approach to #1 is taken. You don't see instances of app.config settings being passed around to every method/function that needs to read a setting. I normally do VB.NET, for which there is a static My.Settings class that basically achieves the same thing as your #1.
The biggest disadvantage I see to #2 (and probably why it is less common) is that the config class can get passed around a lot. If only a small number of methods actually need to read the config it might be ok, but if many methods need to read the config it starts to become a headache. In my opinion it also clutters up the method signatures. Imagine a class deep in the library that needs to read the config; you may have to pass the config through several higher level classes just to pass it through to the class that needs it.
I'd recommend at least considering using app.config or web.config as either one of these already have built in functionality for this type of thing.
EDIT
I was waiting for Brannon to respond with an example, but since he hasn't I'll go ahead and chime in. IOC containers are great tools to help with dependency injection, but I wouldn't dream of introducing one just for a settings class. If you were already using one, that might be a different story. Lets suppose that you were already using an IOC container and wanted to use it for your config class. That means you still have method signatures that look like:
Function Add (FirstNumber, SecondNumber, Config)
Admittedly that example is a stretch, but you get the idea. The IOC container will resolve your Config dependency (it will create the config class for you), but you still have the config as a parameter to each method/constructor that needs it.
To be honest some of it comes down to personal preference. Keep in mind that VS/.NET uses #1 out of the box when you use app.config. I know that static classes are frequently frowned upon and rightfully so in many cases, but I think that settings/config classes are exceptions to the rule.
Related
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.
We are working on two product lines that will share the same code.
For functionality that differs, I have both product lines implement the same interface (or base classes in some case) and these types will be created in the Main class (which is separate for both product lines) and passed further downstream.
For code that is deep inside the business logic, it is very hard to have product line specific code. We do not want to user if(ProductLine == "ProductLine1") and else methodology.
So I am planning to implement a Factory class which will have static methods to return NewObject1(), NewObject2() and so on. This Factory class will be registered in the Main class as Factory.RegisterClient(ProductLine1).
So with the above approach, the factory(which internally contains ProductLine1Factor & ProductLine2Factory) knows which type of objects to create.
Do you know a better approach to this problem. Please note that ProductLine1 was already existing and ProductLine2 is something new (but is 90% similar to ProductLine1). We cannot do drastic refactoring such that both product lines exist. We want to do as minimally invasive code changes as possible.
The factory approach typically exposes an interface, but the problem with interfaces is that I cannot expose static types which are also needed.
I would really appreciate if some experts would shed some light.
Your approach sounds fine.
Instead of a custom crafted factory, why don't you use a fully fledged IoC framework like NInject or Unity? You could have the service implemented twice, for each client, and select one in a container configuration file, statically. This way you don't even need to change the single line of your code if you add yet another implementation, you just reconfigure i.e. make some changes in the xml file.
Anyway, an IoC container is just a tool, use it or not, it just replaces your factory (IoC containers are sometimes called "factories on steroids").
My class contains no methods, only several fields, like host, port, labels, channels etc. etc.
I.e. its kind of config.
Should I use regular Class for representing configs? I want to make it obvious to reader that this instance is just a container for other values.
upd My config is pretty big and comes from xml, so it's a tree.
Yes, most likely you should be using class. There are rare case as pointed in other replies to use struct.
Name your class "ContainerForConfigurationProperties", than look at the resulting code. If it looks bad - refactor by changing class name till you are happy. Note that you may find that after coming up with good name some properties no longer fit into your class - it may mean that you class actually was container for several sets of properties - refactor by splitting the class.
If you use a class with public automatic-property getter/setters, then you can easily serialize/deserialize it (say to XML). Especially if the intent is to be consumed by other readers/developers, then using properties will shield them from changes when building against updated versions of your library. It also leaves the door open in the future if you want to implement anything in terms of tracking value changes, issuing events, performing validation, or just straight-up debugging with breakpoints.
Just call it a class, that's fine. It should be obvious what it's supposed to do, hold config info.
You may want to create an Interface in cases where you'll have a number of different config classes. For example, you might have an IConfig interface that has a few properties and then additional interface elements in more config interfaces (IHostConfig, ILabelConfig, etc.) that you can fit together to build your specific classes with a common, understandable, interface.
I have more like desing question as I'm refactoring quite big piece of code that I took over.
It's not modular, basically it's pseudo-object-oriented code. It contains hard coded dependencies, no interfaces, multiple responsibilities etc. Just mayhem.
Among others it contains a great deal of internal calls to class called Audit, that contains methods like Log, Info, LogError etc... That class has to be configured in application config in order to work, otherwise it's crash. And that's the main pain for me. And please, let's focus on that issue in responses, namely making client code independent of logging classes/solutions/frameworks.
And now, I would like those classes, that have that Audit class dependency hardcoded, refactored in order to obtain several benefits:
First is to extract them nicely to different assemblies, as I will need some functionality available in other applications (for instance generating attachments code - let's call it AttachmentsGenerator class, that until now was specyfic to one application, but now that code could be used in many places)
Remove internal dependencies so that other application that will take advantage of my AttachmentsGenerator class without the need to add reference to other
Do a magic trick in order to allow AttachmentsGenerator class to report some audit info, traces etc. But I don't want it to have hardcoded implementation. As a matter of fact, I don't want it to be mandatory, so it would be possible to use AttachmentsGenerator without that internal logging configured and without the necessity for the client code to add reference to another assemblies in order to use logging. Bottom line: if client code wants to use AttachmentsGenerator, it adds reference to assembly that contains that class, then it uses new operator and that's all.
What kind approach can I use in terms of design patterns etc to achieve it? I would appreciate some links to articles that address that issue - as it can be timeconsuming to elaborate ideas in answer. Or if you can suggest simple interface/class/assembly sketch.
Thanks a lot,
Paweł
Edit 1: As my question is not quite clear, I'll rephrase it once again: This is my plan, are there other interesting ways to do this?
Seems like the easiest way to do this would be to use dependency injection.
Create a generic ILogger interface with methods for logging.
Create a concrete implementation of ILogger that just does nothing for all the methods (e.g. NullLogger)
Create another concrete implementation that actually does logging via whatever framework you choose (e.g. log4net)
Use a DI tool (spring, structure map, etc.) to inject the appropriate implementation depending on whether or not you want logging enabled.
Implement logging (and any other cross-cutting concerns) as a Decorator. That's way more SOLID than having to inject some ILogger interface into each and every service (which would violate both the Single Responsibility Principle and DRY).
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.