Pass information within Forms - c#

This is more of a theoretical question, but I was wondering what's the best way to pass information within forms. I'll explain my issue:
I have my Mainform class which manages the whole application:
public class Mainform : Form
{
private static AddressBook _addressbook = new AddressBook();
private static TemplateManager _templateManager = new TemplateManager();
/*...*/
}
Furthermore, I have another class which is created by Mainform:
public partial class TemplateLists : Form
{
//To be filled with Mainform's information.
private List<Template> _genericTemplates;
private Client _clientToFill;
//In this case, I decided to pass the information through the constructor.
public TemplateLists(List<Template> genericTemplates, Client client)
{
InitializeComponent();
_genericTemplates = genericTemplates;
_clientToFill = client;
}
}
The issue is that, in order for TemplateLists to recieve the _genericTemplates information, I don't know if it's best done through the constructor, a method or public properties and why. In any case, I know how to implement them all, but I don't know which is best and I don't have any reasons to pick one over another.

Basically your whole question can be brought down to when should one use constructor (ctor) parameters vs properties.
Constructor parameters:
These should be used to set mandatory values on your instance. In other words these are the values without which your class instance cannot function.
Class properties:
These should be used when the values are optional for your object's functioning.
Consider an example, wherein your class pulls data via a service (which in turn talks to database etc). Also you intend to perform some sort of logging. In this case, you know that your class will not work without a service instance but you logging can be optional for this class. So while instantiating StoreManager you have option to set logger if you wish.
public class StoreManager
{
private readonly IService dataService;
public StoreManager(IService dataService)
{
if(dataService == null)
{
// Do not allow to go further.
throw new ArgumentException();
}
this.dataService = dataService;
}
public ILogger Logger
{
get;
set;
}
public IList<Product> GetProducts()
{
var products = dataService.GetProducts();
// logging is optional
if(Logger != null) {
Logger.Trace("Products fetched {0}", products.Count);
}
}
}

Better to use Dependency Injection or Service Location. Check this and this for reference.

There is no such thing as "the best" solution. It really comes down to how the form is used. For example it depends what the generic templates are. If they are necessary for the form to be created, it's a good idea to pass it via constructor to prevent that the form is instanciated incomplete.
If they are optional you could assign the after the form is created.
The implementation details (dependency injection, concrete coupling, etc.) depends on how the form is going to be used.

Related

How do I require consumers a of class library to initialize static variables

I am creating a DLL with lots of classes (also subclass).One of them (kind of main class) has public static property like:
public static Guid Token { get; set; }
Then I send the compiled file to another person. The person connects the DLL as a reference to his / her project and then uses the particular class.
Is there an pattern / elegant way to force user to fill static property with value before using any class?
You cannot force somebody to do this.
You can document that it needs to be done, but we all know how well that works.
You can throw an exception if it isn't done, preferably with a descriptive error message and a description how to solve this.
Even better would be to actually pass this Token to all methods that need it. That way it's really obvious they need to pass it. In addition, it's even threadsafe and they can pass multiple tokens at different times to different methods.
If you have to work with static properties then you could require consumers to call an Initialize method:
public void InitializeThisGuidThatYouMustInitialize(Guid guid)
{
// throw an exception if it's empty. Maybe throw an exception
// if it's already been initialized.
_theStaticGuid = guid;
}
Then, within your library, when you need that Guid, call a method that returns the Guid if it's been initialized and throws an exception if it isn't.
Something like this
internal Guid GetTheGuidINeed()
{
if(_theStaticGuid == Guid.Empty) // or use nullable
// Don't make them guess.
throw new Exception("Really clear, helpful exception.");
return _theStaticGuid;
}
This is only if you're tied to the static implementation. If there are lots of these values then you could use an immutable settings class. Require the consumer to initialize with an instance of the class, and validate the values in the class's constructor.
Another approach which eliminates the static property altogether is if you can write a class to configure your library for a DI container which is used by the consumer. Here's an example using Windsor:
public interface IMyLibrarySettings
{
Guid TheGuidINeed { get; }
}
public class MyLibrarySettings : IMyLibrarySettings
{
public MyLibrarySettings(Guid theGuidINeed)
{
TheGuidINeed = theGuidINeed;
}
public Guid TheGuidINeed { get; }
}
public class MyLibraryWindsorFacility : AbstractFacility
{
private readonly IMyLibrarySettings _settings;
public MyLibraryWindsorFacility(IMyLibrarySettings settings)
{
_settings = settings;
}
protected override void Init()
{
// validate the settings, make sure they didn't leave stuff out
// throw awesome clear exception messages.
Kernel.Register(Component.For<IMyLibrarySettings>().Instance(_settings));
// register the other dependencies in your library.
}
}
Now the consumer would call
var settings = new MyLibrarySettings(guidThatTheySupply);
var facility = new MyLibraryWindsorFacility(settings);
container.AddFacility(facility);
You can do the same thing with Unity, Autofac, etc.
Now you're killing lots of birds with one stone. Your library configures its dependencies in the consumer's container, and in order to do so it requires the consumer to provide the needed settings values. When individual classes need those settings, just inject that interface into their constructors, which you can do because that type is registered with the container to return the instance that the consumer provided.
I prefer this over requiring the consumer to pass that value into the constructor unless it's a class that the consumer explicitly creates. I don't want the consumer to know what all of the various classes depend on.
A simple solution could be to just add a constructor that accepts this guid as a parameter. That way, the user is required to set it through the constructor, and the class cannot be instantiated without a valid guid:
public class YourClass
{
public YourClass(Guid token)
{
// Validate token and throw exception if not valid
Token = token;
}
public static Guid Token { get; set; }
}
With this approach, the dependencies become clear as well. Additionally, you can put a check in the set as well to make sure it cannot be set to Guid.Empty.

How to decorate class that relies on a runtime value for creation

I'm brand new to using Simple Injector although I have been using Ninject for a long time, so I am comfortable with DI in general. One thing that attracted me to want to use Simple Injector was the ease of use of Decorators.
I have been able to successfully use decorators with Simple Injector in all normal cases where the dependencies are resolved when the service is requested. However, I am having a hard time figuring out if there is a way to get my decorators applied in a case when the service must be constructed using a runtime value.
In Ninject, I could pass a ConstructorArgument to the kernel.Get<IService> request that could be inherited down the chain of N decorators all the way to the "real" implementing class. I cannot figure out a way to replicate that using Simple Injector.
I have put some very basic code below to illustrate. What I would want to do in the real world would be to pass an IMyClassFactory instance into other classes in my application. Those other classes could then use it to create IMyClass instances using the IRuntimeValue they would provide. The IMyClass instance they got from the IMyClassFactory would be decorated automatically by the registered decorators.
I know I could manually apply my decorator(s) in my IMyClassFactory or any Func<IMyClass> I could come up with, but I would like it to "just work".
I keep going around and around trying to abstract out the MyClass construction, but I can't figure out how to get it to resolve with the IRuntimeValue constructor argument and be decorated.
Am I overlooking an obvious solution?
using System;
using SimpleInjector;
using SimpleInjector.Extensions;
public class MyApp
{
[STAThread]
public static void Main()
{
var container = new Container();
container.Register<IMyClassFactory, MyClassFactory>();
container.RegisterDecorator(typeof (IMyClass), typeof (MyClassDecorator));
container.Register<Func<IRuntimeValue, IMyClass>>(
() => r => container.GetInstance<IMyClassFactory>().Create(r));
container.Register<IMyClass>(() => ?????)); // Don't know what to do
container.GetInstance<IMyClass>(); // Expect to get decorated class
}
}
public interface IRuntimeValue
{
}
public interface IMyClass
{
IRuntimeValue RuntimeValue { get; }
}
public interface IMyClassFactory
{
IMyClass Create(IRuntimeValue runtimeValue);
}
public class MyClassFactory : IMyClassFactory
{
public IMyClass Create(IRuntimeValue runtimeValue)
{
return new MyClass(runtimeValue);
}
}
public class MyClass : IMyClass
{
private readonly IRuntimeValue _runtimeValue;
public MyClass(IRuntimeValue runtimeValue)
{
_runtimeValue = runtimeValue;
}
public IRuntimeValue RuntimeValue
{
get
{
return _runtimeValue;
}
}
}
public class MyClassDecorator : IMyClass
{
private readonly IMyClass _inner;
public MyClassDecorator(IMyClass inner)
{
_inner = inner;
}
public IRuntimeValue RuntimeValue
{
get
{
return _inner.RuntimeValue;
}
}
}
Edit 1:
Ok, thanks to Steven for the great answer. It has given me a couple of ideas.
Maybe to make it a little more concrete though (although not my situation, more "classic"). Say I have an ICustomer that I create at runtime by reading a DB or deserializing from disk or something. So I guess that would be considered a "newable" to quote one of the articles Steven linked. I would like to create an instance of ICustomerViewModel so I can display and manipulate my ICustomer. My concrete CustomerViewModel class takes in an ICustomer in its constructor along with another dependency that can be resolved by the container.
So I have an ICustomerViewModelFactory that has a .Create(ICustomer customer) method defined which returns ICustomerViewModel. I could always get this working before I asked this question because in my implementation of ICustomerViewModelFactory I could do this (factory implemented in composition root):
return new CustomerViewModel(customer, container.GetInstance<IDependency>());
My issue was that I wanted my ICustomerViewModel to be decorated by the container and newing it up bypassed that. Now I know how to get around this limitation.
So I guess my follow-up question is: Is my design wrong in the first place? I really feel like the ICustomer should be passed into the constructor of CustomerViewModel because that demonstrates intent that it is required, gets validated, etc. I don't want to add it after the fact.
Simple Injector explicitly lacks support for passing on runtime values through the GetInstance method. Reason for this is that runtime values should not be used when the object graph is constructed. In other words, the constructors of your injectables should not depend on runtime values. There are several problems with doing that. First of all, your injectables might need to live much longer than those runtime values do. But perhaps more importantly, you want to be able to verify and diagnose your container's configuration and that becomes much more troublesome when you start using runtime values in the object graphs.
So in general there are two solutions for this. Either you pass on the runtime value through the method call graph or you create a 'contextual' service that can supply this runtime value when requested.
Passing on the runtime value through the call graph is especially a valid solution when you practice architectures like this and this where you pass on messages through your system or when the runtime value can be an obvious part of the service's contract. In that case it is easy to pass on the runtime value with the message or the method and this runtime value will also pass through any decorator on the way through.
In your case this would mean that the factory creates the IMyService without passing in the IRuntimeValue and your code passes this value on to the IMyService using the method(s) it specifies:
var service = _myServiceFactory.Create();
service.DoYourThing(runtimeValue);
Passing through the runtime value through the call graph however is not always a good solution. Especially when this runtime value should not be part of the contract of the message that is sent. This especially holds for contextual information use as information about the current logged in user, the current system time, etc. You don't want to pass this information through; you just want it to be available. We don't want this, because this would give an extra burden to the consumers of passing the right value every time, while they probably shouldn't even be able to change this information (take the user in who's context the request is executed for instance).
In that case you should define service that can be injected and allows retrieving this context. For instance:
public interface IUserContext {
User CurrentUser { get; }
}
public interface ITimeProvider {
DateTime Now { get; }
}
In these cases the current user and the current time aren't injected directly into a constructor, but instead these services are. The component that needs to access the current user can simply call _userContext.CurrentUser and this will be done after the object is constructed (read: not inside the constructor). Thus: in a lazy fashion.
This does mean however that the IRuntimeValue must be set somewhere before MyClass gets invoked. This probably means you need to set it inside the factory. Here's an example:
var container = new Container();
var context = new RuntimeValueContext();
container.RegisterSingle<RuntimeValueContext>(context);
container.Register<IMyClassFactory, MyClassFactory>();
container.RegisterDecorator(typeof(IMyClass), typeof(MyClassDecorator));
container.Register<IMyClass, MyClass>();
public class RuntimeValueContext {
private ThreadLocal<IRuntimeValue> _runtime;
public IRuntimeValue RuntimeValue {
get { return _runtime.Value; }
set { _runtime.Value = value; }
}
}
public class MyClassFactory : IMyClassFactory {
private readonly Container _container;
private readonly RuntimeValueContext context;
public MyClassFactory(Container container, RuntimeValueContext context) {
_container = container;
_context = context;
}
public IMyClass Create(IRuntimeValue runtimeValue) {
var instance = _container.GetInstance<IMyClass>();
_context.RuntimeValue = runtimeValue;
return instance;
}
}
public class MyClass : IMyClass {
private readonly RuntimeValueContext _context;
public MyClass(RuntimeValueContext context) {
_context = context;
}
public IRuntimeValue RuntimeValue { get { return _context.Value; } }
}
You can also let the MyClass accept the IRuntimeValue and make the following registration:
container.Register<IRuntimeValue>(() => context.Value);
But the disallows verifying the object graph, since Simple Injector will ensure that registrations never return null, but context.Value will be null by default. So another option is to do the following:
container.Register<IMyClass>(() => new MyClass(context.Value));
This allows the IMyClass registration to be verified, but will during verification still create a new MyClass instance that is injected with a null value. If you have a guard clause in the MyClass constructor, this will fail. This registration however disallows MyClass to be auto-wired by the container. Auto-wiring that class can come in handy when you've got more dependencies to inject into MyClass for instance.

Two services dependend on eachother (stackoverflow exception) - how to solve?

I am new to dependency injection, and I am trying to solve an issue. I have two services. Each of these services have methods who need eachother.
For instance: SiteManager have methods where it needs my ForumManager. My ForumManager have methods where it needs my SiteManager.
I have the following two classes:
public class SiteManager:ISiteManager
{
public IForumManager ForumManager { get; set; }
public SiteManager()
{
this.ForumManager = new ForumManager();
}
}
public class ForumManager:IForumManager
{
public ISiteManager SiteManager { get; set; }
public ForumManager()
{
this.SiteManager = new SiteManager();
}
}
Very obviously this will result in a stack overflow exception, as they call eachother. I've read a lot of posts here, and I think I just need a small hint on how to solve this. I have my interfaces in their own assembly.
I thought about putting the dependencies in their own property so when they are used, they are made. However, is this best practice?
I do not use an IoC container (and I haven't used that before).
Any hints on how to solve this particular issue in a "best practice" way! :-)
You should not be calling new within your classes, that will tightly couple them. The correct pattern for IOC that will allow you to test each class separately using mocks is:-
public class SiteManager:ISiteManager
{
private readonly IForumManager forumManager;
public SiteManager(IForumManager forumManager)
{
this.forumManager = forumManager;
}
}
public class ForumManager:IForumManager
{
private readonly ISiteManager siteManager;
public ForumManager(ISiteManager siteManager)
{
this.siteManager = siteManager;
}
}
But, that doesn't solve the mutual recursion. The easiest way to solve that is to not use constructor injection for one of the classes, but use property injection instead, i.e. put the SiteManager back to a public property on the ForumManager and set it after creating both objects.
Your setup code then does:-
IForumManager forumManager = new ForumManager();
ISiteManager siteManager = new SiteManager(forumManager);
forumManager.SiteManager = siteManager;
Another alternative would be to pass a ForumManagerFactory into the SiteManager, e.g. a Func<ISiteManager,IForumManager>.
ISiteManager siteManager = new SiteManager((s) => new ForumManager(s));
Inside the site manager you can then call the Func, passing this to get the IForumManager. The ForumManager gets an instance of the SiteManager and the SiteManager has the ForumManager object.
When using MVP with winforms and AutoFac, I had this exact same issue with the view referencing the presenter and the presenter referencing the view. The way I got around it is to have one of your classes pass itself to the other using an Initialize method. I am not sure if this is best practice, but I have seen it suggested before (this question about mvp)
So for the implementation details:
public class SiteManager:ISiteManager
{
public IForumManager ForumManager { get; set; }
public SiteManager()
{
}
public Initialize(IForumManager forumManager)
{
ForumManager = forumManager
}
}
public class ForumManager:IForumManager
{
public ISiteManager SiteManager { get; set; }
public ForumManager(ISiteManager siteManager)
{
this.SiteManager = new SiteManager();
this.SiteManager.Initialize(this);
}
}
Edit Actually would probably go with the other solutions posted, I was just looking at this purely from a circular dependency point of view
what you are doing and what you are suggesting both will cause stack overflow exception. i don't know why will you want to do something like that and you are not giving any hints on that but i guess i can offer you to create a manager, maybe a singleton, maybe just with static method and do:
public static void DoStuff(ISiteManager sm, IForumManager fm)
{
// your code here can use the best of both without SO
}
and not holding ISiteManager in ForumManager and IForumManager in SiteManager
You clearly can't have interdependant classes. What you need to do is to create a separate class and move there the methods which use the same time forum manager and sitemanger: Here is a sample 3rd class:
class ForumAndSiteManager
{
public ForumAndSiteManager(ISiteManager siteMaanger, IForumManager forumManager)
{
//save the injected object to private fileds
}
//define methods which will use both sitemanager and forum manager
}
This way you will brake the circular depedency
You should definitely avoid circular dependencies. I mean A depends on B and B on A.
This is like a cancer of your context dependencies. We used spring.net framework which contrary to java's version is unable to switch on a failing system if it discovers this kind of dependency. I have to say that this brings us only mess and hours of spring's logs searching and analyzing.
We defined almost 200 without any problem but once we added just another bean along with Lazy reference it failed down. This is almost impossible to untangle our solution to avoid it right now so we hook and hook and hook whilst it fails :-(

Prevent a subclass of a singleton class from calling the singleton's constructor

Ok, I have a singleton class GraphMaster which contains a number of system-wide values. I have a subclass GraphObject : GraphMaster which has graph specific data. By subclassing, I can access members of either the global class or subclass. And by using a singleton class, I can change the global variables anywhere and have them be reflected in all the subclasses.
However, I'm getting stuck because the base class's constructor wants to call the singleton class's constructor, but it can't as it's marked private.
how do I get around this? Is what I'm trying to do possible? I went down this path due to responses to this post: Can I make a "global" object to store variables for multiple objects?
For example,
public class GraphMasterObject {
private static GraphMasterObject instance;
private GraphMasterObject() { }
}
public static GraphMasterObject Instance {
get {
if (instance == null) instance = new GraphMasterObject();
return instance;
}
}
public int globalVar=10;
}
public class GraphObject : GraphMasterObject {
public GraphObject() {
}
public int localVar=20;
}
I want to be able to do
GraphObject go = new GraphObject();
go.globalVar <- this is 10
GraphMasterObject.Instance.globalVar = 20;
go.globalVar <- now this is 20
Ok, I have a singleton class GraphMaster which contains a number of system-wide values. I have a subclass GraphObject : GraphMaster which has graph specific data.
That's a problem to start with. As soon as you have a class which has subclasses, that it by definition not a singleton. Someone can add another subclass at any point, and even if you only have one instance of each subclass, you'll have two distinct instances which are compatible with the base class.
You could add something in the base class constructor to throw an exception if there's already an instance, but it would be pretty smelly. Fundamentally, singletons are incompatible with subclassing. Rethink your design. (Ideally, avoid the singleton pattern in the first place, but that's another matter...)

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.

Categories

Resources