Best Pattern for Storing Common Settings across Multiple Classes - c#

I'm creating two separate classes for accessing a custom file. Let's call my classes MyReader and MyWriter.
I'm following the same pattern that .NET classes such as StreamReader and StreamWriter follow, where there is a separate class for reading and writing. In addition to following an established pattern, this also solved some other problems for me.
However, I really need a few common settings for both the reader and writer classes. For example, I have a delimiter character that the user should be able to change. I also have some fixed data that contains common information used for parsing.
Could someone suggest a good pattern, especially one that follows common .NET framework practices, for creating common settings for multiple classes like this? My classes already inherit from a .NET class. Seems like multiple inheritance might have been one way but doesn't seem supported in C#.
(I'm using Visual Studio 2012.)

public interface IStreamFilter
{
string Delimiter {get; private set;}
List<string> FilterCriteria {get; private set;}
}
public class StreamFilter : IStreamFilter
{
public string Delimiter {get;}
public List<string> FilterCriteria {get;}
public void StreamFilter (string delimiter, List<string> filterCriteria)
{
this.Delimiter = delimiter;
this.FilterCriteria = filterCriteria;
}
}
You can pass an instance of IStreamFilter in the constructor of your Reader and Writer Class.
public class MyReader
{
private IStreamFilter _streamFilter;
public MyReader(IStreamFilter streamFilter)
{
this._streamFilter = streamFilter;
}
public string ReadString()
{
var readString = reader.GetString(x => x.Contains(this._streamFilter.Delimiter);
// apply the filter for reading string
}
}
Anywhere in your code where you want to instantiate MyReader class, you can create a new instance of IStreamFilter, and set the delimiter and other filter criteria as per user preference (let's say from user profile), in the constructor. Then you pass that instance of StreamFilter to your MyReader instance. That way, you can customise the filter settings on the fly without relying on Singletons.

This seems to be one of those rare instances where a Singleton might make good sense:
public abstract class MyBase
{
// This is the .NET class you're inheriting from, just putting it as a placeholder.
}
public class MyReader : MyBase
{
private static readonly IMySettings settings = MySettings.Instance;
}
public class MyWriter : MyBase
{
private static readonly IMySettings settings = MySettings.Instance;
}
internal interface IMySettings
{
// Define your setting's properties, such as delimiter character.
}
internal sealed class MySettings : IMySettings
{
private MySettings()
{
}
public static IMySettings Instance
{
get
{
return Nested.Instance;
}
}
// Implement your setting's properties, such as delimiter character.
private static class Nested
{
private static readonly IMySettings instance = new MySettings();
// Explicit static constructor to tell C# compiler not to mark type as beforefieldinit
static Nested()
{
}
public static IMySettings Instance
{
get
{
return instance;
}
}
}
}
Hope this helps.

Try using interfaces. interface works like abstract class but can only contain method or property definitions that are to be "fleshed out" by the classes that implement them. Classes can then implement as many interfaces as you need. Take a look at how IEnumerable allows lists, dictionaries, and arrays to all share a common set of methods, allowing them to be used in foreach, or how IDisposable allows a class to be declared in using.
I made a set of ink textbox controls that are all supposed to get their display style settings from the user config of multiple applications, so I made them grab those settings from an IInkInputSettings interface and implemented that interface in all of the applications' UserConfig classes.
Alternatively, you could achieve global configuration by way of a Singleton:
public class GlobalConfig{
/* your configuration properties here */
private static GlobalConfig instance = null;
public static GlobalConfig Instance{
get{
if(instance == null) instance=new GlobalConfig();
return instance;
}
}
private GlobalConfig(){ /* set default property values */ }
}
This is better than a static class with static members, because it is only instantiated the first time you use it.

You could use constructor-based dependency injection to insert a settings class into the classes. It would be simple enough to get an IoC container to spin up a settings class, singleton or not, and inject it based on base class or interfaces.

Related

Alternative way(s) of structuring these objects in C# language

My goal is something along these lines:
// Defines members, for the "change-log" of the API,
// if the interface has changed, the API has a new major version.
// For "automatically generating changelogs" (for major versions) of the API
interface IApp
{
static string Name { get; set; }
}
// Internal class, not for usage outside of the dll
internal static class AppConfig
{
internal static bool IsPublished;
}
// Public available members from the API
public static class App : AppConfig, IApp
{
public static string Name { get; set; }
}
Now, there are a few wrongs in the structure above, based on C# language:
The interface cannot have static members
The class App is static, so it cannot inherit a static class
The AppConfig is static, so it cannot be inherited from
The class App is static, so it cannot have an interface
My current "solution":
public static partial class App
{
internal static bool IsPublished;
}
public static partial class App
{
public static string Name { get; set; }
}
Which I wanted to add contracts/interfaces to... So, I would maybe end up with something along these lines, "wrapping" APP:
public static class App
{
private static _App app;
static App()
{
app = new _App();
}
public static string Name { get { return app.Name; } }
}
internal interface _IApp
{
string Name { get; set; }
}
internal class _App : _AppConfig, _IApp
{
public string Name { get; set; }
}
internal class _AppConfig
{
internal static bool IsPublished;
}
This is long, tedious and boring. Three places to update insert a new member: Interface, _App-class (implementation) and in the static App-class (for API-users).
I want to achieve two things: A contract, interface, which defines all major changes from one version to another (read interfaces, print to change-log).
Making things that shall not be used for users of the API private (internal...).
The question? Anyone done something similar before, how did you solve it? Or talk me into forgetting the idea of a changelog based on interfaces... Because interfaces requires non-static objects, while I want static objects (at least on this particular object, it is static!).
PS: Atm. I read all public objects/members of the API to a log, which is now the "changelog". But starting on a new API, wanted to do something... different. :)
Edit: Note; I care about how the object looks on the "other side", it is an important thing. User of the API, to call App-members, shall be as simple as this (straight forward):
System.Windows.App.Name;
Which means the "outer class" (or however you want to look at it), is a static object.
Last note: I have several (12-15) objects of this "type", so I wanted a elegant structure, for all objects, all named similarly, so if you get to know one object, you know them all. Meaning: if one object has an interface, all others has one too. If one object is named "AppConfig", you can bet your life on that the other object also has a class named "OtherConfig". :)
It sounds like you're trying to have different "flavors" of the same class. Each one shares some common functionality? If so, I would use an abstract class as the base instead of an interface. Then, derive the other classes from that one. Unlike an interface, the abstract class will allow you to provide implementations at the parent level (e.g.: saving the object to disk or database). You can read more here: https://msdn.microsoft.com/en-us/library/sf985hc5.aspx.
I also agree with Filkolev, this doesn't sound like something that you would want a static class for.

Multiple Classes With Same Methods

I have many classes in a project that need to all have a base set of the same constructors and 1 public method. Below is an example of this partial class:
public partial class SHIPMENT_LINE
{
private OracleConnection _rp = null;
private EntityConnection _rpe = null;
private static string _schema = "";
public SHIPMENT_LINE() { }
public SHIPMENT_LINE(BHLibrary.Configuration.ConnectionOption Environment)
{
SetConnection(Environment);
}
public void SetConnection(BHLibrary.Configuration.ConnectionOption Environment)
{
this._rp = Configuration.RPConnection(Environment);
this._rpe = Configuration.RPEntityConnection(Environment, out _schema);
}
}
I need to implement the same private variables, constructors, and the SetConnection method on each of my classes that I create. After this all exists in each class, then each class will do something different, so the classes are not all necessarily related, aside from the fact that they all have this same "Beginning."
How should I go about building each of these classes so that I do not have to implement this SetConnection method in each of the classes that I create?
Keep this in mind:
Due to other restrictions, I cannot inherit from another class in any of these classes. I can, however, use Interfaces if necessary.
I would suggest going for composition rather than inheritance...
Make each of the class implement an interface, then have another class (not related to these) which also implements the interface and has a concrete implementation of it. All the classes you've mentioned above should have an instance of this additional class and just call through to it.
Example
public partial class SHIPMENT_LINE : ISetConnection
{
private ConnectionSetter connector = new ConnectionSetter();
public void SetConnection(BHLibrary.Configuration.ConnectionOption Environment)
{
this.connector.SetConnection(Environment);
}
}
public class ConnectionSetter : ISetConnection
{
public void SetConnection(BHLibrary.Configuration.ConnectionOption Environment)
{
// Implementation
}
}
If you can't subclass then an abstract class is not a viable solution and interfaces are only going to give you the contract that your common classes conform to without any implementation.
I would suggest implementing the common functionality in a common class and using this as a private member in your other classes (I.E. composition rather than inheritance). Your other classes could all implement an interface to ensure they all have the same methods and they could just forward their calls onto the private classes implementation of the method.
E.G.
private MYClassWithCommonFunctionality xyz = new MYClassWithCommonFunctionality();
And then...
Private void MyCommonInterfaceMethod(object param)
{
// Do derived class specific stuff here...
xyz.MyCommonInterfaceMethod(param);
}
And as an added bonus and a bit of forward thinking....have the common class also share the same interface and pass an implementation of this into your other classes constructor. That way in the future you can swap the implementation for another.
If you cannot create a base class that will implement your common functionality (any reason why?) than you probably can use T4 template to generate partial class with your common methods.

Sharing an instantiated class among multiple objects in C#

I currently have a class which I instantiate when I start my program. The class itself will create a new thread and begin to search for broadcasts from routers.
I have other windows, other then MainWindow, which needs to be able to access the data stored within the instance of this class. However, I'm not sure as to how the other windows can reference this data.
Is there some other way I can store the instance of this class so that it is accessible application wide? I need it to start right when the rest of the application starts, so it seemed logical (to me) to have the class be instantiated in the first window.
namespace Lalu_WPF
{
public partial class MainWindow : Window
{
// data storage for program
public FindRouter finder = new FindRouter();
public MainWindow()
{
......
Don't make Singleton (notice the capital letter). It is error prone in multiple threads environments(muttable Singletons) and bad for testing.
What are your requirements?
Do you have to have one object in one application or one object in whole CLR?
I bet the first one.
Make an object in your App class (App.xaml.cs) and then acces it via getter
App MyApplication = ((App)Application.Current);
MyApplication.Router;
Don't use a Singleton, it makes unit testing hard and your code surprising.
Give classes which need access to an instance the instance. That means that every class which needs this single instance should accept either by a constructor argument or setter. Whoever creates the class is then in charge of supplying the dependency. This is called Dependency Injection.
You could make the class a singleton and this way you could access this same instance across the entire application. You can see an example on the msdn website here
Do you have a Program class? In the Windows Forms projects that I do, variables such as that go in Program public static readonly members or in public static properties with get only.
What you're talking about sounds like the Singleton design pattern. You could create a singleton object, a static class, or (what I like) a Monostate object (an object that encapsulates the static class or single instance) , something like this:
public class SingletonWidget
{
private static readonly Implementation SingleInstance ;
public void DoSomething( int someValue )
{
SingleInstance.DoSomething( someValue ) ;
return ;
}
public int SomeProperty
{
get
{
return SingleInstance.SomeProperty ;
}
set
{
SingleInstance.SomeProperty = value ;
}
}
static SingletonWidget()
{
SingleInstance = new Implementation() ;
return ;
}
private class Implementation
{
public void DoSomething( int someValue )
{
// ...
}
public int SomeProperty { get ; private set ; }
}
}
Usage looks like normal object instantation:
SingletonWidget foo = new SingletonWidget() ;
foo.DoSomething(3) ;
but under the covers, there's just a single instance hanging around. Changing from a static class or singleton is trivial as only the wrapper needs to change. Building stubs or mocks is pretty easy, too.
It makes it easy to
Try a DI framework or some less complex implementation of a service locator. That will allow you to provide the instance where it is needed throughout your app without hardcoding in a singleton, which is then painful to write tests around.
I know that Ninject at least provides support for single instances application-wide. I haven't used it in a WPF application but I can't see why not.
As a basic example of a service locator you could do something like the following. I've called the shared class Foo:
public interface IFoo { ... }
public class Foo { ... }
public class ServiceLocator
{
IFoo _foo = new Foo();
public IFoo GetFoo() { return _foo; }
}
public class DependsOnFoo
{
public IFoo Foo = ServiceLocator.GetFoo();
...
}
DependsOnFoo.Foo is the shared instance of Foo by default but when writing automated tests you could swap it out with a stub or mock:
var testTarget = new DependsOnFoo();
testTarget.Foo = mockFooImplementation;
// now testTarget isn't bound to the Foo implementation
As far as I understand your question is how to store a reference to your finder rather than how to create it. If this is the case I would suggest using IDictionary Application.Current.Properties property, which is nothing but a collection of application-scope properties. At startup you can create your object and store a reference to it like this:
Application.Current.Properties["finder"] = new FindRouter();
Then, in any place of your program you can access it like
FindRouter finder = (FindRouter)Application.Current.Properties["finder"];
Hope this helps.

Static Class as an Instance Property

I have an interface based class that I want to have a few static classes as properties. However, I can't seem to find a way to use a static class as an instance property on a class based on an interface.
public interface IHttpHelp
{
ItemsManager {get;set;}
}
public static class ItemsManager
{
//static methods
}
public class HttpHelper
{
public ItemsManager { get { return ItemsManager;}
}
The above code won't work because of the "ItemsManager is used like a variable but it's a type error." Is there anyway to use a class this way?
For some insight into what I'm doing - I have a few static helper classes that access the httpruntime and current context. I currently use them directly, but wanted to move into a container class that will be used IoC. I could make them instance classes and forget about it, but I'm wondering f there's a way to this.
You can't use a static class like that, because by definition you can't create an instance of it, so you can't return it from a property. Make it a singleton instead:
public class ItemsManager
{
#region Singleton implementation
// Make constructor private to avoid instantiation from the outside
private ItemsManager()
{
}
// Create unique instance
private static readonly ItemsManager _instance = new ItemsManager();
// Expose unique instance
public static ItemsManager Instance
{
get { return _instance; }
}
#endregion
// instance methods
// ...
}
public class HttpHelper
{
public ItemsManager ItemsManager { get { return ItemsManager.Instance; } }
}
This is not supported by the language directly. You can either write a proxy class manually or use a library like the Duck Typing Project to emit a proxy class at runtime.
Both will have the same result: you will have a class that implements the interface, and proxies all calls to the static methods of the static class. Whether you want to write this yourself or use the duck typing library is up to you.
EDIT: Thomas' answer of using a singleton would be the way to go, if you have that option.
Static classes can't implement interfaces--it really wouldn't make much sense. An interface provides a standard API that all instances will support and you can swap instances and polymorphically access the methods through the standard interface. With a static class, all references to it are through the class anyways.
Typically in this situation you want a factory to support DI of an instance class that implements your helper.
public interface IHttpHelper
{ }
public class RealHttpHelper
{ ... }
public class FakeHttpHelper
{ ... }
public static class HttpHelper
{
public static IHttpHelper Instance
{
get
{
return whatever ? new RealHttpHelper() : new FakeHttpHelper();
}
}
}
...
HttpHelper.Instance.Context...
...

oop: Composition or Inheritance in concrete case

We've just had a discussion with college about is the following style acceptable for oop or not.
We've a class, which has one public function, and requires a reader in the constructor:
public class Converter
{
private readonly IReader _reader;
public Converter(IReader reader)
{
_reader = reader;
}
public byte[] Convert(...params...)
{
return something;
}
}
We have Reader1 and Reader2 which both implement an IReader.
I want to setup two managers: Converter1 and Converter2, providing the same public Convert() function, but Converter1 will be using Reader1, and Converter2 will use Reader2.
For me the simplest solution is to inherit from Converter and initialize it with proper reader:
public class Converter1 : Converter
{
public Converter1():base(new Reader1())
{}
}
public class Converter2 : Converter
{
public Converter2():base(new Reader2())
{}
}
My college says, that Converter1 and Converter2 are Managers, and inheritance should not be used for managers, instead we should apply a composition here. But from my perspective composition will only result in additional code in specific converters classes.
So, could you please advice, whether it is ok to use inheritance when implementing managers or not?
Thanks
Why are you inheriting at all??
Based on the sample you have provided, you are not doing anything additional to the base class other than ensuring that Converter1/Converter2 enforces a specific type of reader.
It seems to me that your collegue is right. What you should be doing is implementing a Factory Method, that will create and populate the correctly configured Converter for you.
i.e.
public static class ConverterFactory {
public static CreateConverter1() {
return new Converter(new Reader1());
}
public static CreateConverter2() {
return new Converter(new Reader2());
}
}
...
Converter x = ConverterFactory.CreateConverter1();
To my mind, this is an abuse of inheritance. You aren't specializing the behaviour of the converter - you're only specializing the construction.
In particular, you could easily have a static class with static methods to perform this construction:
public static class Converters
{
public static Converter CreateConverter1()
{
return new Converter(new Reader1());
}
public static Converter CreateConverter2()
{
return new Converter(new Reader2());
}
}
These could even be static methods within the normal Converter class, of course.
The fact that this loses no functionality suggests to me that inheritance was a mistake.
Then again, I'm regularly suspicious of inheritance. Designing inheritance properly means working out the extension points, documenting how they should behave - which is a balancing act between giving callers enough information to predict consistent behaviour, and giving implementors enough wiggle room to vary the behaviour in useful ways. Here you're not doing any of this - you're just changing what reader is passed to the constructor.
Either use inheritance (like you proposed), or just use one Converter class which will work with the polymorphic IReader.

Categories

Resources