(Disclaimer: This question is not specific to ASP.NET)
I have a control which may be templated, similar to the login controls:
public abstract class TemplatedControl : CompositeControl
{
public ITemplate Template { get; set; }
protected override void CreateChildControls()
{
var template = this.Template ?? CreateDefaultTemplate();
// ...
}
protected virtual ITemplate CreateDefaultTemplate()
{
return null;
}
}
A templated control would look like:
public class FooControl : TemplatedControl
{
public override ITemplate CreateDefaultTemplate()
{
return new FooTemplate();
}
}
My question is: would a Singleton be appropriate here instead?
public override ITemplate CreateDefaultTemplate()
{
return FooTemplate.Instance;
}
Singletons are associated with global variables; in this case, there is no state.
Singletons are also associated with hard-coded dependencies. In this case, knowledge of the specific type is warranted.
In this case I would say not. In the pattern you are proposing, there would only ever be one FooTemplate, which would be shared across multiple controls, pages and threads. You would have to be very careful that the template did not contain any request or user specific information, and also synchronize any method calls. It is much easier, and just a bit less performant to instantiate it each time.
The only reason I see doing it that was is that it takes a long time to instantiate the control. In that case, I would go with a factory pattern, where any initialization is done once, but all the data copied into a new instance every time.
If you only want the template created once for the control, you could use lazy initialization instead and achieve nearly the same effect.
private ITemplate defaultTemplate;
public override ITemplate CreateDefaultTemplate()
{
if (defaultTemplate == null)
{
defaultTemplate = new FooTemplate();
}
return defaultTemplate;
}
You should only use a Singleton implementation if you are sure that you only want one instance of any particular object ever in your application.
Do you really want to use the exact same instance for the template control? We may need some more info about what you are trying to accomplish. How many places does TemplatedControl get used in the same application?
Related
With Unity, I can inject various controls/interfaces via constructor like following:
private readonly IEmployeeRepository _employeeRepository;
public EmployeeView_EmployeeListViewModel(IEmployeeRepository employeeRepository)
{
_employeeRepository = employeeRepository;
}
However, I need to access the specific control (let's say the one used in an example) outside of the constructor (I cannot edit constructor).
Is there a way, how to do it?
EDIT
more info - I have a DataForm, which allows users to do simple CRUD operations on their DataGrid (simple edit form). This control is from Telerik inc. and therefore it's commands class looks like following:
public class CustomDataFormCommandProvider : DataFormCommandProvider
{
public CustomDataFormCommandProvider():base(null)
{
}
protected override void MoveCurrentToNext()
{
if (this.DataForm != null)
{
this.DataForm.MoveCurrentToNext();
this.DataForm.BeginEdit();
}
}
protected override void MoveCurrentToPrevious()
{
if (this.DataForm != null)
{
this.DataForm.MoveCurrentToPrevious();
this.DataForm.BeginEdit();
}
}
protected override void CommitEdit()
{
if (this.DataForm != null && this.DataForm.ValidateItem())
{
this.DataForm.CommitEdit();
}
}
protected override void CancelEdit()
{
if (this.DataForm != null)
{
this.DataForm.CancelEdit();
}
}
}
If by any means I change the constructor, commands stop working (therefore I cannot put my Interface into the constructor).
What I need to do, is under CommitEdit, except for updating the usercontrol, I also want to do a separate call, which would save particular user's changes under the database (my IEmployeeRepository takes care of all).
That's why I need to find a way, how to achieve it this 'proper' way. I can surely re-style the template of this control and rebind OK & Cancel buttons, but I don't believe that's the way to go.
FINAL
ServiceLocator did the job. Here is the code:
_employeeRepository = Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance<IEmployeeRepository>();
There's ServiceLocator.Current.GetInstance which can provide you with any dependency everywhere.
But be careful, as the dependency is pretty much hidden.
I need an architectural advice.
I have two classes:
public class Shell
{
public IPage CurrentPage { get; set; }
public void ChangePage(IPage page)
{
CurrentPage = page;
}
}
public class SomeFunctionallityClass
{
private readonly Shell _shell;
private readonly IPage _somePage;
public Model1(Shell shell, IPage page)
{
_shell = shell;
_somePage = page;
}
public void MakeSomeCrazyStuff()
{
_shell.ChangePage(_somePage);
}
}
In Shell class i have a CurrentPage property and this is the property which very many classes in the application want to have access to.
Right now i pass Shell object to the classes which need to change the page.
But what will be the best way to give access to the same class for many other classes?
Actually your solution of passing the Shell class to each other class that requires it, is not too bad, especially if you do it via the constructor.
Sure, the most common ways to do this are using the Singleton or a class with static methods. But if you are honest, in this context both of them are nothing but masked global state.
The original purpose of the singleton is to make sure only one object of a class exists, not to make something easily accessible. However the latter is the most common reason why developers use it. Other people therefore call it the "King of Antipatterns" :)
To be honest, I use both the Singleton and static methods myself in some cases to make my life easier (in the short term). But I never feel good about it.
To summarize, as far as I know you have three basic options:
Pass object in constructor
Singleton
Static methods
All of these have their pros and cons, but I consider the first solution the cleanest because it does not introduce global state.
You might want consider using Singleton design pattern:
https://msdn.microsoft.com/en-us/library/ff650316.aspx
Choose the one that fully answers your requirements.
You can make your Shell static:
public static class Shell
{
private static IPage CurrentPage { get; set; }
public static void SetCurrentPage(IPage page)
{
CurrentPage = page;
}
}
public class SomeOtherClass
{
public vod ShowShellPropery()
{
MessageBox.Show(Shell.Property);
}
}
Also having a setter ChangePage, you should make your CurrentPage private. Otherwise, you have two ways of changing your current page: with the setter ChangePage(page), and with CurrentPage = page, which is not good. Also I renamed your setter ChangePage to SetCurrentPage, so now it is clear that it is a setter
I'm trying to model a production system with "facility" as Class and some subclasses down to "Activity". The facility has a name as only parameter (at the moment), and I'd like to create an instance of the class reading the name as an input from a textbox. Since "activity" is inherit the properties from it's "parent classes" I'll create an instance of the class "activity" and not it's parent.
The problem is that I don't know where to create the class and how to pass it so that when I add the first subclass "Workstation" I can edit the properties of the same "activity" I created earlier.
I don't really have any code to add at this point unfortunately, but please tell me if there's anything special you'd like to see and I'll try to add it to the post.
And by the way, it's in the shape of a WinForm application with a GUI I'm trying to do this.
There are a couple things to note here. First, you'll want to use the Composite pattern to encapsulate the relationships between your classes. (For those who don't understand the OP's type hierarchy, it does make perfect sense in a factory context. There are many activities going on, which can be grouped into workstations and at a higher level into facilities.)
So, you should probably have a base Activity class (that supports the Composite pattern by exposing a collection of child activities), and then your "levels" (like Facility and Workstation) will inherit from Activity. Each of these classes will have unique properties.
The following classes should be created in their respective files, e.g. Activity.cs, Factory.cs, Workstation.cs:
class Activity
{
// An attribute that every Activity may need: a displayable name.
// This might be useful if you have a TreeView, e.g., showing all the activities.
public string Name { get; private set; }
// Every Activity could have child activities - this is the Composite pattern.
// You can loop through these to navigate through the hierarchy of your data.
// (This is often done using recursion; see example below with GetAllWorkstations().)
public List<Activity> ChildActivities { get; private set; }
public Activity()
{
ChildActivities = new List<Activity>();
}
public override string ToString() { return Name; }
}
class Factory : Activity
{
public string City { get; private set; }
public string Address { get; private set; }
}
class Workstation : Activity
{
public string WorkstationNumber { get; private set; }
}
The responsibility of loading your model then has to be handled somewhere. A good place to do it is in your main form. For example, you might write code like this:
class MainForm : Form
{
private readonly List<Factory> topLevelFactoryActivities;
public MainForm()
{
// ... other code
topLevelFactoryActivities = LoadTopLevelFactoryActivities();
}
private IEnumerable<Factory> LoadTopLevelFactoryActivities()
{
var factories = new List<Factory>();
// TODO: Load the factories, e.g. from a database or a file.
// You can load all the child objects for each factory here as well,
// or wait until later ("lazy-loading") if you want to.
// NOTE: If this becomes complex, you can move the LoadTopLevelFactoryActivities()
// method to its own class, which then becomes your "data access layer" (DAL).
return factories;
}
}
Now, if you want to find all the workstations that are part of a particular factory, you would write a method like the following on the Factory class:
class Factory : Activity
{
// ... other code
public IEnumerable<Workstation> GetAllWorkstations()
{
return GetWorkstationsRecursive(this);
}
private IEnumerable<Workstation> WorkstationsIn(Activity parentActivity)
{
foreach (var workstation in parentActivity.ChildActivities.OfType<Workstation>)
{
// Uses a C# feature called 'iterators' - really powerful!
yield return workstation;
}
foreach (var childActivity in parentActivity.ChildActivities)
{
// Using recursion to go down the hierarchy
foreach (var workstation in WorkstationsIn(childActivity))
{
yield return workstation;
}
}
}
}
You would call it like so, e.g. in your main form:
class MainForm : Form
{
// ... other code
public MainForm()
{
// ... other code
// Assume this is assigned to the factory that you want to get all the workstations for
Factory myFactory;
var workstations = myFactory.GetAllWorkstations();
// Now you can use 'workstations' as the items source for a list, for example.
}
}
As an example use case, you might want to show a second form (that belongs to the main form) which shows a list of all the workstations. (In practice you probably shouldn't create too many windows; prefer building a nonoverlapping layout. But just to show how you might pass the model instances around...)
class WorkstationListForm : Form
{
private IEnumerable<Workstation> workstations;
public WorkstationListForm(IEnumerable<Workstation> workstations)
{
this.workstations = workstations;
//TODO: You can now use 'workstations' as the ItemsSource of a list view in this form.
}
}
You could, of course, make topLevelFactoryActivities public on your MainForm and pass the variable this of the MainForm to the WorkstationListForm constructor instead. Then you could access the member on MainForm like this:
public WorkstationListForm(MainForm mainForm)
{
var topLevelFactoryActivities = mainForm.topLevelFactoryActivities;
// Now WorkstationListForm has full access to all the data on MainForm. This may or
// may not be helpful (it's usually best to minimize sharing and public fields).
}
Second, you'll want to use a proper separation between your view (user interface code/classes) and your model (the Activity hierarchy).
Third, if there's going to be any kind of live data being pushed to the user interface then you'll need a databinding mechanism to automatically update the view whenever the model changes.
In general, #2 & #3 are popularly addressed via the Model-View-ViewModel pattern. There is an excellent tutorial here for building an MVVM app using WinForms/C#.
That should get you started, at least. Also see an answer to a similar question. (Sorry about promoting my own answer, but I don't want to type out the whole example twice. Please forgive me. :))
I have two classes that I'd like to keep in separate files.
namespace GridSystem
{
public class Grid
{
public void AddItem(GridItem item)
{
item.InformAddedToGrid();
}
}
}
namespace GridSystem
{
public class GridItem
{
public void InformAddedToGrid()
{
Debug.Log("I've been added to the grid");
}
}
}
How do I ensure no other classes are allowed to call InformAddedToGrid?
I'm trying to emulate Actionscript namespaces, which can be used on a method, in place of public, private, internal, etc. It doesn't exactly protect the method, but forces an extra step of including the namespace before the method can be accessed. Is there an alternative approach to this in C#?
If GridItem itself can be hidden from the outside world as well I would consider putting GridItem inside Grid as a nested class. That way it won't be visible outside of the class
http://www.codeproject.com/Articles/20628/A-Tutorial-on-Nested-Classes-in-C
Not that you should do this, you should do what TGH suggests, have a public interface for GridItem, and have gridItem nested in Grid (then have a factory method on Grid to create Items and use partial Grid class to have them in separate files).
Because there isn't a way of having friend methods ( you can do friend classes through InternalsVisibleToAttribute )
You COULD do this ( but don't... )
public partial class Grid
{
public void AddItem(GridItem item)
{
item.InformAddedToGrid();
}
}
public class GridItem
{
public void InformAddedToGrid()
{
if (new StackTrace().GetFrame(1).GetMethod().DeclaringType !=
typeof(Grid)) throw new Exception("Tantrum!");
Console.WriteLine("Grid called in...");
}
}
then
var g = new Grid();
g.AddItem(new GridItem()); // works
new GridItem().InformAddedToGrid(); // throws a tantrum...
A really ugly answer would be to make it private and use reflection.
Another ugly answer would be to make it throw an exception if the caller is wrong.
Both of these are much slower to execute than a normal call also.
I don't think there's a good answer. C# doesn't have friends.
IMHO the answer is simple: access modifiers are just there to remind the programmer of the intent of how public/private a class should be. Through reflection you can lift those barriers.
The usage you make of a class is all in your hands: if your class is meant to only be used in one place, make it so. If anything, if a class has a special way of being used, document it - put it in the XML comments.
That said, in this specific example I'd believe since the GridItem doesn't add itself to the grid, it's not its job to notify about it (what if "I've not been added to the grid"?). I think InformAddedToGrid belongs somewhere in your Grid class as a private method, where there's a concept of adding an item... assuming that's what AddItem(GridItem) really does.
You can do it as TGH suggested, with nested classes, except the other way around. Nest Grid within GridItem and make InformAddedToGrid private. Here I use a nested base class so the public API can remain the same. Note that no one outside of your assembly can inherit from GridBase because the constructor is internal.
public class GridItem
{
public class GridBase
{
internal GridBase() { }
public void AddItem(GridItem item)
{
item.InformAddedToGrid();
}
}
private void InformAddedToGrid()
{
Debug.Log("I've been added to the grid");
}
}
public class Grid : GridItem.GridBase { }
Another option is to have GridItem explicitly implement an internal interface. This way no one outside of your assembly can use the interface by name and therefore cannot call InformAddedToGrid.
public class Grid
{
public void AddItem(GridItem item)
{
((IGridInformer)item).InformAddedToGrid();
}
}
public class GridItem : IGridInformer
{
void IGridInformer.InformAddedToGrid()
{
Debug.Log("I've been added to the grid");
}
}
internal interface IGridInformer
{
void InformAddedToGrid();
}
I have some classes inherit from existing Windows Controls like TextBox and DateTimePicker, ..etc
I want to add custom functionalities for these classes like (Read, Alert, ...etc)
these added functionalities are the same in all these classes
The problem is: these classes inherited from difference parents so I can't put my added functionalities in the parent class,
What's the best practice in this case:
repeat the code in each inherited
class
Use a separated class have the
functionalities as Static Methods
with parameter from an interface, implement this interface for the classes and
then pass them.
Use a separated class like the second approach but with Dynamic parameter (which added in C# 4.0)
or other !!
Thanks in advance
I'd consider option 4: composition.
First, define your set of functionality. We'll assume that your partial list is exclusive, so "Read" and "Alert."
Second, create a single class that implements this functionality, something like MyCommonControlBehaviors. I'd prefer this implementation not be static if possible, though, it may be generic.
public MyCommonControlBehaviors
{
public Whatever Read() { /* ... */ }
public void Alert() {}
}
Third, use composition to add an instance of this class to each of your custom control types and expose that functionality through your custom control:
public class MyCustomControl
{
private MyCommonControlBehaviors common; // Composition
public Whatever Read() { return this.common.Read(); }
public void Alert() { this.common.Alert(); }
}
Depending on specifics, you can get creative to the degree necessary. E.g., perhaps your custom behaviors need to interact with private control data. In that case, make your control implement a common ICommonBehaviorHost interface that your common behaviors need. Then pass the control into the behavior class on construction as an instance of ICommonBehaviorHost:
public interface ICommonBehaviorHost
{
void Notify();
}
public class MyCommonControlBehaviors
{
ICommonBehaviorHost hst = null;
public MyCommonControlBehaviors(ICommonBehaviorHost host)
{
this.hst = host;
}
public void Alert() { this.hst.Notify(); } // Calls back into the hosting control
// ...
}
public class MyCustomControl : ICommonBehaviorHost
{
private MyCommonControlBehaviors common = null;
public MyCustomControl() { common = new MyCommonControlBehaviors(this); }
public Whatever Read() { return this.common.Read(); }
public void Alert() { this.common.Alert(); }
void ICommonBehaviorHost.Notify() { /* called by this.common */ }
}
Use Composition instead of Inheritence!
If you must, what I would probably do is create extension methods for each class and then reference the actual coded needed for these in some other object all the extension methods can call.
This way the code isn't duplicated, and the extension methods make it look like the methods should be in the object.
It's the same essentially by creating a static method and doing: Functions.DoSomething(my_Object);
But I always like: my_Object.DoSomething() better in an OO language.
I would suggest defining an interface for the behaviors, and then (to keep from repeating yourself) create extension methods on that interface definition for your shared methods. (Kinda like your second option, only with extension methods instead of totally static methods).