Storing global immutable data in static classes - c#

I have a WinForms project, which uses a lot of user controls. Some of these user controls use classes from business logic layer. These classes are mainly performing CRUD operation to a database (through data access layer) plus some additional validation and reporting.
The project uses some common objects (logged user, some controllers and validators), which are instantiated in main form and then injected into child user controls via initialization methods or public properties. This means, that I have a lot of code, which just passes these common objects from parent control to child controls.
In order to avoid this, I could create a static class (ApplicationContext for example) and save all common controls into it. This would happen in the main form and all other user controls or forms in the project could use it.
I see that this pattern is discouraged in general (storing some global data in static classes). But what if this data is immutable? Is this approach ever a good idea?
Or do you know any other approach, which could help me get rid of all the initialization code?

You can use an Inversion of Control container like Unity or Autofac and have it automatically wire up your object graph for you.
You can have each object that requires any one of the common objects define a dependency to their interfaces, either though a constructor argument, or as a public property, and the IoC container will wire the appropriate objects together.
Property injection example with Unity:
public class MyUserControl : UserControl
{
[Dependency]
public LoggedUserService UserService { get; set; }
public void Method()
{
// the IoC container will ensure that the UserService
// property has been set to an object
}
}
All you do in the main form is registering the common objects you want the IoC container to know about and then you ask for the root object. The object graph will be assembled magically for you and you don't have to to all the wire code nor care how it is done.

You can use a dependency injection / ioc container for maintaining your global objects.
I have made good experience with the autofac library but there are many other available.
When using setter injection, all of your controls get set dependent objects set automatically.

You'll want to use Singletons for this situation. Singletons will allow you to use the same instance of your object, more safe and flexible than static.
public sealed class Singleton
{
public object Property1 {get;set;}
public void Method1 (){}
static Singleton instance = null;
static readonly object padlock = new object();
Singleton()
{
}
public static Singleton Instance
{
get
{
lock (padlock)
{
if (instance==null)
{
instance = new Singleton();
}
return instance;
}
}
}
}
then you can use it like you would static, but a bit different...
public class Main
{
public Main()
{
Singleton.Instance.Property1 = "somevalue";
Singleton.Instance.Method1();
}
}

You can use a static class to store some immutable data - no problem with this.
How ever if you want to store controls there it might not work as expected.
For example method like OnDataBinding and Render.

Related

Why using the factory pattern when a simple dependecy injection is enough

Im looking to this example to understand the use of factory pattern.
I'm really amator in this field so excuse my silly question.
My problem is that i don't see the use of the factory pattern which return us the interface that we can inject it directly when we need to use it.
In the example above I would do something like this:
public class Program
{
// register the interfaces with DI container in a separate config class (Unity in this case)
private readonly IShippingStrategy _shippingStrategy;
public Program(IShippingStrategy shippingStrategy)
{
_shippingStrategy= shippingStrategy;
}
public int DoTheWork(Order order)
{
// assign properties just as an example
order.ShippingMethod = "Fedex";
order.OrderTotal = 90;
order.OrderWeight = 12;
order.OrderZipCode = 98109;
int shippingCost = _shippingStrategy.CalculateShippingCost(order);
return shippingCost;
}
}
Instead of injecting the factory :
public class Program
{
// register the interfaces with DI container in a separate config class (Unity in this case)
private readonly IShippingStrategyFactory _shippingStrategyFactory;
public Program(IShippingStrategyFactory shippingStrategyFactory)
{
_shippingStrategyFactory = shippingStrategyFactory;
}
public int DoTheWork(Order order)
{
// assign properties just as an example
order.ShippingMethod = "Fedex";
order.OrderTotal = 90;
order.OrderWeight = 12;
order.OrderZipCode = 98109;
IShippingStrategy shippingStrategy = _shippingStrategyFactory.GetShippingStrategy(order);
int shippingCost = shippingStrategy.CalculateShippingCost(order);
return shippingCost;
}
}
Why taking the bruden to create a factory (thus adding an extra layer) when we can inject the interface directly to wherever we need to use it ?
I think you don't want just another article about the factory pattern but a short comprehensive answer.
So, I'd like to focus on two things.
More flexibility
Most commonly, you'd set up your composition root where you basically say ...
"if anyone wants IAnyService, he should get MyAnyServiceImplementation".
This is fixed for your application. Once set up, your dependency injection container will serve the class instances you registered but you should not try to re-configure that container again. That's perfect for startup flexibility like registering implementation for data access components by the application's configuration, for example. Say ...
"if anyone wants IUserRepository, he should get MsSqlUserRepository because we are working with MSSQL server".
Of course, having that "immutable" composition root limits the possibilities to choose an implementation in runtime depending of the applications' state.
Instead you can inject a class which decides on a current state which service implementation to choose. Data validation is a typical scenario for that pattern because there might be different rules for different entities on your system. The buzzword here is "rule pattern" or "strategy pattern".
Lifetime control
Think of a long-living class instance like a view (user interface) or any class attached to it (like a viewmodel or a controller). As long as a user is active on a view, the class is alive. By injecting a class instance to the constructor of the view controller, for example, you hold an active instance of it as long as the view lives.
Let's say you want to use a data repository to connect to a database for example. These database access calls should be short and you do not want to keep connections open for a long time. With a repository factory, you could control the lifetime very precisely and make sure that the class is removed after it has been used:
using (var repository = new _factory.CreateRepository(...))
{
return repository.GetAnything();
}
With this, a very lightweight class - the factory - gets injected and lives as long as the view controller lives. The heavy classes - the connection things - should not live long and are just created when needed.
In fact, chances are that the repository is not instantiated at all if there's no requirement to load the data (because of an upfront cache hit, for example). If you would have injected the repository directly, you'd guarantee that one long living instance lives in memory in every case.
If you check the code for the factory you can see that depending on the ShippingMethod of the order a different implementation of the IShippingStrategy is returned by the factory. Since the ShippingMethod is only known once DoTheWork has been called it's impossible to inject the right implementation when the class is constructed (and the same class might even need different implementations for different orders).

C# Singleton - Basic Implementation and strategy

New C# devloper and programmer in general. I am hoping to gain insight into the overall proper usage of a Singleton, with insight on properly accessing class items. I cannot seem to figure out how this is done properly.
Background:
I am developing a C# WPF Application, employing MVVM.
The goal of my Singleton is to provide a globally-accessible class, where I am able to update the values inside within my Model.
This Singleton is called out at the top of my ViewModel, using the following syntax:
public CurrentMDL_Singleton currentMDL_Singleton = CurrentMDL_Singleton.Instance;
One of my ViewModels contains the following class:
public class CurrentMDL_Singleton
{
private static CurrentMDL_Singleton instance;
private CurrentMDL_Singleton()
{
CurrentMDL_Constructor currentMDL_Constructor = new CurrentMDL_Constructor();
}
public static CurrentMDL_Singleton Instance
{
get
{
if(instance == null)
{
//Create a new instance
instance = new CurrentMDL_Singleton();
}
return instance;
}
}
}
Knowledge Check:
I intend to use this Singleton to create an instance of "currentMDL_Constructor". currentMDL_Constructor is another class which exists within the same ViewModel, seen below:
public class CurrentMDL_Constructor
{
public Microsoft.Office.Interop.Excel.Application CurrentMDL_Excel { get; set; }
public Microsoft.Office.Interop.Excel.Workbook CurrentMDL_Workbook { get; set; }
public Microsoft.Office.Interop.Excel.Worksheet CurrentMDL_Worksheet { get; set; }
public Microsoft.Office.Interop.Excel.Range CurrentMDL_xlRange { get; set; }
}
Problems:
I am unable to access the currentMDL_Constructor instance, created by the Singleton, as the Singleton constructor is a private member (understandable given the Singleton's purpose).
Within my Model, I am trying to tap into currentMDL_Constructor, to conduct something like the following:
CurrentMDL_Excel = new Microsoft.Office.Interop.Excel.Application();
CurrentMDL_Workbook = CurrentMDL_Excel.Workbooks.Open(MainWindow.MDL_Compare_VM.CurrentMDL_File);
I am unable to access currentMDL_Constructor to begin even thinking about having access to my CurrentMDL_Constructor class.
What is it that I am not understanding? I feel like I am getting lost in the world of instantiation, nested classes and a lack of basic knowledge with Singleton usage, and object orientation in general.
Thank you in advance, and I apologize if this post is redundant (could not find one that helped me).
-Chris
Your code has multiple issues:
First, when writing a singleton that has no dependencies to other classes like in your case, it is best practise to have a static readonly field that holds the single instance, but you should instantiate it straight away like so:
private static CurrentMDL_Singleton instance = new CurrentMDL_Singleton();
This is because, whenever you reference a singleton class, you will probably use its instance. Moving the instantiation to a field init moves it into the type loader and therefore makes it thread-safe. In your code, if clients access the Instance property in parallel, you may end up in a race condition and hence with two different instances of a singleton class, which is something that you would typically want to avoid.
Second, your constructor creates an object and does not save it anywhere, hence you can't access it.
Third, there is absolutely no need to have an instance variable holding a singleton instance, because you can always get it from the static instance field. In your case, it is even dangerous because someone could change it to null and you would not notice.
Lastly, you should really reconsider whether it is really a singleton that you need. A singleton pattern is applied to make sure that there is only one instance of a class, usually not because it is easier to query its contents, because it is a dependency that you cannot easily exchange.
Access the singleton via the public property Instance.
Access the CurrentMDL_Constructor fields as follows:
CurrentMDL_Singleton.Instance.CurrentMDL_Excel
CurrentMDL_Singleton.Instance.CurrentMDL_Workbook
CurrentMDL_Singleton.Instance.CurrentMDL_Worksheet
CurrentMDL_Singleton.Instance.CurrentMDL_xlRange
Thanks to all who helped with this. I was able to figure out where my problems mostly originated from, which was with the layout of the Singleton class.
I want to mention my reasoning for using this Singleton class. I need to ensure only one instance of these Excel variables exists. This is important because my ViewModel and Model depend on referencing instances of the same items. I have been struggling with closing these Excel files because I was mixing up instances. These Excel files are very large, need to remain open in between application functions and close directly after the second function. The Singleton design model solves the problem of ensuing a single instance, and also allows me to access the instance from within my Model very effortlessly.
Knowledge Check : Where I Went Wrong:
My previous understanding was that the private constructor within the Singleton class would set up what I would need to reference after the Singleton was instantiated. This was the wrong thinking.
Don't use the private constructor to instantiate or reference anything; this goes against the main use of the Singleton class. All we're trying to do is make sure only one instance of this Singleton exists; the pivate constructor is there to solely create the Singleton Instance to reference later.
The Fix :
Remove "CurrentMDL_Constructor" class, pull the items that were in that class, which I was trying to create a reference for, into the Singleton main class.
public class CurrentMDL_Singleton
{
public Microsoft.Office.Interop.Excel.Application CurrentMDL_Excel { get; set; }
public Microsoft.Office.Interop.Excel.Workbook CurrentMDL_Workbook { get; set; }
public Microsoft.Office.Interop.Excel.Worksheet CurrentMDL_Worksheet { get; set; }
public Microsoft.Office.Interop.Excel.Range CurrentMDL_xlRange { get; set; }
private static CurrentMDL_Singleton instance = null;
private CurrentMDL_Singleton() {}
public static CurrentMDL_Singleton Instance
{
get
{
if(instance == null)
{
//Create a new instance
instance = new CurrentMDL_Singleton();
}
return instance;
}
}
}
CurrentMDL_Excel, CurrentMDL_Workbook, CurrentMDL_Worksheet, etc. are now all accessible through calling out the instance within the Singleton (thank god). Within my Model, I'm now able to to the following:
> CurrentMDL_Singleton.Instance.CurrentMDL_Excel = new Microsoft.Office.Interop.Excel.Application();
My next step is making this Singleton thread-safe.
Thanks again for the help, and I hope this helps someone else who is trying to understand how to implement Singletons.
-Chris

How to create a class without constructor parameter which has dependency injection

I have added the dependency injections to the project. But when i create an instance by using new keyword, dependency injection doesn't work.
public class MyClass
{
ILoginTokenKeyApi _loginTokenKeyApi;
public MyClass(ILoginTokenKeyApi loginTokenKeyApi)
{
_loginTokenKeyApi = loginTokenKeyApi;
}
...
}
When i try to create an instance of MyClass, it wants a parameter to be constructed naturally.
Just like this :
MyClass mc = new MyClass(); // ERROR, it wants a parameter (but it is what i want)
I have to do :
MyClass mc = new MyClass(new LoginTokenKeyClass()); // this is not a good code for me
How i create an instance of MyClass without parameter because it has dependency injected.
But when i create an instance by using new keyword, dependency injection doesn't work.
That’s fundamentally how dependency injection works.
With dependency injection, you are simply not supposed to new up new objects. That’s the whole point of dependency injection and inversion of control. Instead of creating objects and managing those objects’ dependencies, you are depending on the framework to give you the dependencies you need without having you to care about where they actually come from and how they are constructed properly. So you are moving the responsibility to create the object up to the caller.
If you find yourself in need to create an object that has a dependency, then this is a clear sign that you are doing it wrong. A common reason for this is that you want to create the object in order to manage its lifetime, or because it is actually a data object that just happens to have some operations that needs other dependencies to work (e.g. an entity that has a “save” method). In the first case, you simply don’t do it like that. You just depend on it and let the framework manage the lifetime; if it has an incorrect lifetime, then you should reconfigure it with the DI container.
In the latter case where you have a data object with operations, you should split this up. You should just have a data object, without any logic, and then inject some manager service that is able to perform the operation on that data object for you.
For example in ASP.NET Core Identity, you have the User object which is just a normal entity without any logic. In order to e.g. add user roles or change the password, you rely on the user manager which you can inject. So the User object itself is without any dependencies.
I’d generally suggest you to read the dependency injection chapter of the ASP.NET Core documentation to understand how dependency injection works and how it is supposed to be used within the framework.
As mentioned in the comments, it is not clear what you trying to achieve, but in order to do DI in .Net Core you have to create an interface IMyClass, then let your class implement that interface,
public interface IMyClass {
void SampleMethod();
}
public class MyClass : IMyClass
{
ILoginTokenKeyApi _loginTokenKeyApi;
public MyClass(ILoginTokenKeyApi loginTokenKeyApi)
{
_loginTokenKeyApi = loginTokenKeyApi;
}
public void SampleMethod()
{
// method logic goes here...
var xx = _loginTokenKeyApi.WhatEver;
}
}
then register ILoginTokenProvider and IMyClass in startup.cs
services.AddTransient<ILoginTokenProvider, LoginTokenProvider>();
services.AddTransient<IMyClass, MyClass>();
finally inject IMyClass where you need it:
public class IndexModel : PageModel {
private readonly IMyClass _myClass;
public IndexModel(IMyClass myClass)
{
_myClass = myClass;
}
public void OnGet()
{
_myClass.SampleMethod();
}
}
btw, it is also possible to register and inject MyClass without implementing IMyClass interface, but I prefer to follow basic programming principals :)
There are two types of Dependency Injections.
Constructor Injection - which you dont want
Property Injection - In this - you expose Public Get/Set property of the Object you want to be injected. And then in your DI config file (like spring.net) you can assign values.
Another way you can do DepInjection is that in the param less constructor - you can get the Object by a Key/Name. Like in Spring.Net we would do:
var UtilityObject = Spring.ContextRegistry.GetContext().GetObject("MyUtilObject") as TheUtilityClass;

Where to place global variables in MVVM (Caliburn micro)

I'm refactoring a program done in WinForms to WPF and I'm using Caliburn.Micro as a framework to implement the MVVM pattern.
In the old program, I use a StatisHelper class to allow different static variables like the theme, the language, the username or the rights of access, etc ..
I know that it could be insecure because these variables are public, but I doubt that my end users know how to access these values...
Anyway, I would like to know the best practice in MVVM to save global values (in concrete, I'm using Caliburn.Micro framework) that can be accessed for all the view-models.
Thank you for your responses.
You could use a singleton class (frowned upon by some). Note that the constructor is private, so nothing else can create an instance. Use the Instance property to access it. The Instance property in this example will only construct the singleton object the first time it's accessed.
To use it, simply do something like var foo = Globals.Instance.SomeProperty.
Note that this has nothing to do with WPF or MVVM, and could have been used in WinForms as well.
public class Globals {
private Globals _Instance;
public Globals Instance {
get {
if (_Instance == null)
_Instance = new Globals();
return _Instance;
}
}
private Globals() {
}
public string SomeProperty { get; set; }
}
I use a custom StateManager class that implements the Singleton pattern so that there is only one of these instances in the application:
public class StateManager : INotifyPropertyChanged
{
private static StateManager instance = new StateManager();
/// <summary>
/// Initialises a new empty StateManager object.
/// </summary>
public StateManager() { }
/// <summary>
/// Gets the single available instance of the application StateManager object.
/// </summary>
public StateManager Instance
{
get { return instance; }
}
...
}
This is then referenced in my base view model, so that all of my view models have access to it:
public StateManager StateManager
{
get { return stateManager.Instance; }
}
Furthermore, because it is referenced in my view model classes, I can also Bind to the values in XAML:
<Window Title="{Binding StateManager.WindowTitle, Mode=OneWay}" ... />
Well my answer is a combination of ideas from the #Steve and #Sheridan and the link in the comment.
First of all, I have to say separate the data from the code.
As for the data, I would use those Resx files to store all those kinds of resources, whether they are binary resources like simple audio files, images, localizable strings, etc .., because this makes it easy to swap them at run-time.
As for the code, I would use a collection like IConfigurationProvider like this:
public interface IConfigurationProvider {
GetResourceByName<T>(string key); // T is the type of the requested resource
// THIS IS A SIMPLIFIED VERSION, YOU CAN HAVE MORE METHODS
// ACCORDING TO YOUR NEEDS
}
The implementation of this interface could use the Resx files to store and retrieve resources, then you can inject those resources into the different classes that need it.
This haves some advantages like:
Better testability
Can use different media to store the resource data without changing the interface
Swap the implementation at run-time, you can use DI now.
More clear where is the data coming from

IoC/DI in the face of winforms and other generated code

When using dependency injection (DI) and inversion of control (IoC) objects will typically have a constructor that accepts the set of dependencies required for the object to function properly.
For example, if I have a form that requires a service to populate a combo box you might see something like this:
// my files
public interface IDataService {
IList<MyData> GetData();
}
public interface IComboDataService {
IList<MyComboData> GetComboData();
}
public partial class PopulatedForm : BaseForm {
private IDataService service;
public PopulatedForm(IDataService service) {
//...
InitializeComponent();
}
}
This works fine at the top level, I just use my IoC container to resolve the dependencies:
var form = ioc.Resolve<PopulatedForm>();
But in the face of generated code, this gets harder. In winforms a second file composing the rest of the partial class is generated. This file references other components, such as custom controls, and uses no-args constructors to create such controls:
// generated file: PopulatedForm.Designer.cs
public partial class PopulatedForm {
private void InitializeComponent() {
this.customComboBox = new UserCreatedComboBox();
// customComboBox has an IComboDataService dependency
}
}
Since this is generated code, I can't pass in the dependencies and there's no easy way to have my IoC container automatically inject all the dependencies.
One solution is to pass in the dependencies of each child component to PopulatedForm even though it may not need them directly, such as with the IComboDataService required by the UserCreatedComboBox. I then have the responsibility to make sure that the dependencies are provided through various properties or setter methods. Then, my PopulatedForm constructor might look as follows:
public PopulatedForm(IDataService service, IComboDataService comboDataService) {
this.service = service;
InitializeComponent();
this.customComboBox.ComboDataService = comboDataService;
}
Another possible solution is to have the no-args constructor to do the necessary resolution:
public class UserCreatedComboBox {
private IComboDataService comboDataService;
public UserCreatedComboBox() {
if (!DesignMode && IoC.Instance != null) {
comboDataService = Ioc.Instance.Resolve<IComboDataService>();
}
}
}
Neither solution is particularly good. What patterns and alternatives are available to more capably handle dependency-injection in the face of generated code? I'd love to see both general solutions, such as patterns, and ones specific to C#, Winforms, and Autofac.
I believe there is no silver-bullet solution here. I would use property injection in this case to leave parameterless constructor. Also I personally do not like injection of services into UI classes, I prefer injecting some kind of Presenters there. Then you have a property Presenter which will be set by IoC container and in setter of this property you will have your initializing code.
Out of your two solutions I do not like second one especially because of referencing IoC container in your code which is bad IMO.
I would say that your UI, especially sub-elements of your UI, shouldn't need to be provided with any services.
It's hard to judge how feasible this is for your app, but MVC or MVP is meant to avoid this need.
I would try to redesign so that a controller is responsible for interacting with services and that controller gives the view elements everything they need, rather than letting the view elements ask for what they need.

Categories