I'm working on a product calculator program. Inside the app, the rep sale person can search for a client ID and the app shows him what services he can offer to client and his provision for sale. The form is generated acording to data i download from database.
Right now I'm trying to store generated controls in lists. Every time a search is made, I dispose of controls and clear the lists. The thing i cant seem to get working is to store all the lists in single dictionary.
Something like this...
public class ListOfControls<T> : IListOfControls<T> where T : Control
{
private readonly List<T> _controlsList;
public ListOfControls()
{
_controlsList = new List<T>();
}
public void AddControll(T control)
{
_controlsList.Add(control);
}
public T this[int number]
{
get
{
return _controlsList[number];
}
}
public void ClearControls()
{
_controlsList.Clear();
}
public T Last()
{
return _controlsList.Last();
}
}
class DictionaryOfControlsLists
{
//will be private - public only for test
public readonly Dictionary<string, IListOfControls<Control>> _dictionaryOfLists;
public DictionaryOfControlsLists()
{
_dictionaryOfLists = new Dictionary<string, IListOfControls<Control>>();
}
//Other code....
}
Now trying to implement...
DictionaryOfControlsLists _testDict = new DictionaryOfControlsLists();
_testDict._dictionaryOfLists.Add("test", new ListOfControls<Label>());
Sadly this wont work...Any ideas? THANKS
What you need is something like this:
class DictionaryOfControlsLists
{
private readonly Dictionary<Type, IListOfControls<Control>> _dictionaryOfLists = new Dictionary<Type, IListOfControls<Control>>();
public void Add<T>(T control) where T : Control
{
if (!_dictionaryOfLists.ContainsKey(typeof(T)))
{
_dictionaryOfLists[typeof(T)] = new ListOfControls<Control>();
}
_dictionaryOfLists[typeof(T)].AddControl(control);
}
public T Get<T>(int number) where T : Control
{
if (!_dictionaryOfLists.ContainsKey(typeof(T)))
{
_dictionaryOfLists[typeof(T)] = new ListOfControls<Control>();
}
return _dictionaryOfLists[typeof(T)][number] as T;
}
}
Then you can do this:
DictionaryOfControlsLists _testDict = new DictionaryOfControlsLists();
_testDict.Add<Label>(new Label());
Label label = _testDict.Get<Label>(0);
If you need to extend this to have a string key then you need to implement a double dictionary within DictionaryOfControlsLists to handle it - something like a Dictionary<Type, Dictionary<string, IListOfControls<Control>>>.
Related
I have a basic architecture for 'orders' in my game - each order has a basic data type and an 'order processor' which performs some action based on the given data. For example 'move to this point.'
I'd like to have a tidy system where I can simply pass in order data and the correct order processor will kick in, in such a way that I can easily add new OrderData/OrderProcessor classes without modifying other classes or messing around with enums or casting, so it seems like generics are the way to go.
This is the current code I have. I'm drawing a blank for how to draw a connection in the 'OrderService' class between the correct 'OrderProcessor' and 'IOrderData' pairs. See inside the OrderService<T> class for more information:
public interface IOrderData
{
}
// an order processor reads data from an IOrderData object until the data object says stop
public abstract class OrderProcessor<T> where T : IOrderData
{
protected T m_currentData;
public virtual void Start(T data)
{
m_currentData = data;
}
}
////////////////////////
public class MoveOrderData : IOrderData
{
public Vector3 Destination { get; private set; }
}
public class MoveOrderProcessor : OrderProcessor<MoveOrderData>
{
public override void Start(MoveOrderData data)
{
base.Start(data);
}
}
////////////////////////
public class OrderService<T> where T : IOrderData
{
private Dictionary<System.Type, OrderProcessor<T>> m_processors = new Dictionary<System.Type, OrderProcessor<T>>();
private OrderProcessor<T> m_currentProcessor;
public void GiveOrder(IOrderData data)
{
// this is the main problem: I'm not sure how to say "the given data is type 'MoveOrderData' so find out which
// OrderProcessor class handles those and pass it in". A simple switch statement and cast would suffice here
// but I'd like to automate the process
}
}
A possible solution here can be a making an OrderService class non-generic, because it can handle a different types of orders/order processors (according to comments). Then maintain a Dictionary<Type, Action<object>>, which wraps Action<object> to call Start method from OrderProcessor<T>.
I've extended the original code a little bit to show how it can work
public interface IOrderData
{
}
public class MoveOrderData : IOrderData
{
public Vector3 Destination { get; private set; }
}
public class AttackOrderData : IOrderData
{
}
public abstract class OrderProcessor<T> where T : IOrderData
{
protected T CurrentData { get; set; }
public virtual void Start(T data)
{
CurrentData = data;
}
}
public class MoveOrderProcessor : OrderProcessor<MoveOrderData>
{
}
public class AttackOrderProcessor : OrderProcessor<AttackOrderData>
{
}
public class OrderService
{
private readonly Dictionary<Type, Action<object>> m_processors = new Dictionary<Type, Action<object>>();
public OrderService()
{
AddProcessor(new MoveOrderProcessor());
AddProcessor(new AttackOrderProcessor());
}
private void AddProcessor<T>(OrderProcessor<T> processor) where T : IOrderData
{
var action = (Action<T>)processor.Start;
m_processors.Add(typeof(T), obj => action((T)obj));
}
public void GiveOrder(IOrderData data)
{
var action = m_processors[data.GetType()];
action?.Invoke(data);
}
}
It causes a downcasting obj => action((T)obj), but it shouldn't be a problem, since your data is constrained to IOrderData interface. Example of the usage
var service = new OrderService();
service.GiveOrder(new MoveOrderData());
service.GiveOrder(new AttackOrderData());
To explain a little my environment, I need to keep track of users and a collection of things each user own. This is highly dynamic, although the number of base users is always higher than the collection of things they own. I decided to go with something like this:
private static Dictionary<string, Dictionary<string, MyClass>> ActiveUsers =
new Dictionary<string, Dictionary<string, MyClass>>();
In this case, the TKey for the parent Dictionary is the connectionId of an user, and the TKey for the inner dictionary is a string that represents the Id of MyClass
What I meant before is that ActiveUsers will hold (hopefully) a great number of TKeys, while the TValues will normally hold less than 10 items. As these items are related, when a user disconnects, it is deleted from the parent Dictionary, and all other items in the parent Dictionary will be searched for some value in their inner dictionary and these will be deleted if present.
This field will be accessed constantly (extremely often) and I'm trying to achieve the best performance possible.
Is this a better approach (performance-related) than creating a class with an ID and Dictionary<string, MyClass> as fields and holding a list of this class?
Would something like this be better?
public class ActiveUsersManager
{
public string Id{ get; private set; }
public Dictionary<string, MyClass> ActiveUsers { get; private set; }
public ActiveUsersManager(string connectionId)
{
Id = connectionId;
ActiveUsers = new Dictionary<string, MyClass>();
}
}
//In another class
private static List<ActiveUsersManager> ActiveUsers = new List<ActiveUsersManager>();
If it helps, the ActiveUsers is a static field in an ASP.NET Controller.
EDIT: answering comments
This dictionary is consumed as this:
public static MyClass GetInformation(string myId, string objectId)
{
//Validation removed
Dictionary<string, MyClass> dictionaryResult = null;
MyClass result = null;
if (!ActiveUsers.TryGetValue(myId, out dictionaryResult)) //check if the user was already added to the Dictionary
{
dictionaryResult = new Dictionary<string, MyClass>();
result = new MyClass(objectId);
dictionaryResult.Add(objectId, result);
ActiveUsers.Add(myId, dictionaryResult);
}
else if (!dictionaryResult.TryGetValue(objectId, out result)) //otherwise check if the user already has this item
{
result = new MyClass(objectId);
dictionaryResult.Add(objectId, result);
ActiveUsers.Add(myId, dictionaryResult);
}
//else everything is already set-up
return result;
}
EDIT: Code that shows how the inner items are deleted
public static void RemoveUserAndSessions(string userId, string objectId)
{
ActiveUsers.Remove(userId);
foreach (Dictionary<string, MyClass> dic in ActiveUsers.Values)
dic.Remove(objectId);
}
This is the first ASP.NET application I work in, and I haven't done any multithreading that involved dictionaries before, how could I make this thread-safe?
EDIT: trying to make things more clear.
I didn't want to reveal details, but I guess they are needed to understand the reason behind this. This is for a chat application. Each user is stored in ActiveUsers to keep track of, well, active users. Each user has a Dictionary of the clients they are connected with, and the MyClass object contains a set of properties needed for the client to communicate. As soon as a user disconnects, all the active sessions must be immediately deleted, hence the delete method. I imagine this could be done by creating another class to hold active sessions in a Dictionary and have this class in the original Dictionary.
As suggested, I'll take a look at the ConcurrentDictionary
I strongly advise structuring the data more like this:
private static ConcurrentDictionary<string, ActiveUser> ActiveUsers { get; set; }
private class ActiveUser {
public int ConnectionId { get; set; }
public Dictionary<string, MyClass> MyClasses { get; set; } = new Dictionary<string, MyClass>();
}
// . . .
Dictionary<string, ActiveUser> ActiveUsers = new Dictionary<string, ActiveUser>();
(Note: If you are using C# < 6, just initialize the dictionary in the ActiveUser constructor)
And for your delete method, you may want to do something such as:
public static void RemoveUserAndSessions(string userId, string objectId)
{
ActiveUsers.Remove(userId);
Parallel.ForEach(ActiveUsers.Values, dic => dic.Remove(objectId));
}
Edit: Renamed some things for clarity.
The main problem from performance perspective I see in your design is the need to iterate all the dictionaries during the RemoveUserAndSessions method. Here is a sample design that does not have that problem
static class UserManager
{
private static readonly Dictionary<string, User> ActiveUsers = new Dictionary<string, User>();
public static User GetInformation(string userId)
{
lock (ActiveUsers)
{
User user;
if (!ActiveUsers.TryGetValue(userId, out user))
ActiveUsers.Add(userId, user = new User(userId));
return user;
}
}
public static void RemoveUserAndSessions(string userId)
{
lock (ActiveUsers)
{
User user;
if (ActiveUsers.TryGetValue(userId, out user))
{
ActiveUsers.Remove(userId);
user.EndAllSessions();
}
}
}
public static void StartSession(string firstUserId, string secondUserId)
{
lock (ActiveUsers)
{
var firstUser = GetInformation(firstUserId);
var secondUser = GetInformation(secondUserId);
firstUser.StartSession(secondUser);
secondUser.StartSession(firstUser);
}
}
}
class User
{
private Dictionary<string, User> sessions = new Dictionary<string, User>();
public string Id { get; private set; }
public User(string id) { Id = id; }
public void StartSession(User other)
{
sessions.Add(other.Id, other);
}
public void EndSession(User other)
{
sessions.Remove(other.Id);
}
public void EndAllSessions()
{
foreach (var other in sessions.Values)
other.EndSession(this);
sessions.Clear();
}
}
This is just to get the idea, hope you can map it to your concrete case.
public class Classname
{
private static nameOFform Somevariable;
public static nameOFform GlobalForm
{
get
{
if (Somevariable == null || Somevariable.IsDisposed)
{
Somevariable = new nameOFform();
}
return Somevariable;
}
set
{
value = Somevariable;
}
}
}
Is it doable to put this method in a class and just call it in an instance function let's say => classname.makemyformglobal(formname); Which will be used each time a form is created to make it globalalize. is this possible? if it is then how can I make one method that is dynamic base on a form name created.
If I correctly understood your question, you're looking into something which is usually implemented in c# with Generics.
public static class GlobalFormAccessor
{
private static Dictionary<Type, object> _cache = new Dictionary<Type, object>();
public static TForm GetForm<TForm>()
where TForm : class, new()
{
if (_cache.ContainsKey(typeof(TForm)))
{
_cache[typeof(TForm)] = new TForm();
}
return (TForm)_cache[typeof(TForm)];
}
public static void SetForm<TForm>(TForm form)
{
_cache[typeof (TForm)] = form;
}
}
You could then call this method like:
GlobalFormAccessor.GetForm<nameOFform>();
where nameOFform is the type of your Form class.
I have a ton of methods like this:
public UIPCompanyButton AddCompanyButton (string name, Company company, UIEventListener.VoidDelegate methodToCall, GameObject contents)
{
return UIPCompanyButton.Create (name, company, methodToCall, contents);
}
that I'd like to replace with a single method like this:
public T AddButton<T,K>(string name, K item, UIEventListener.VoidDelegate methodToCall, GameObject contents) where T:UIPMenuButton
{
return T.Create(name, item, methodToCall, contents);
}
which obviously doesn't work at the T.Create part. Is there a certain syntax I need to do this?
I'm also open to a different method with the same result: a single method that takes in a derived menuButton and creates the right one with the right class of "item".
No, you can't call static methods on generic types - not without reflection. Aside from anything else, there's no way of constraining a generic type to have specific static members. The closest to that is the parameterless constructor constraint.
What you want is a factory to create your objects. Here is a small working example. It might not be the best way to implement a factory pattern, but it should get you going.
For a more in depth example and explanation, see this page.
public class Button {
public string Whatever { get; set; }
public Button() {
Whatever = "Hello, world!";
}
}
public interface IAddButton {
Button CreateButton();
}
public class ClassToMakeButtonFor1 {
public static void RegisterMe() {
ButtonFactory.Register(typeof(ClassToMakeButtonFor1), new ButtonFactory1());
}
}
public class ButtonFactory1 : IAddButton {
public Button CreateButton() {
return new Button();
}
}
public class ClassToMakeButtonFor2 {
public static void RegisterMe() {
ButtonFactory.Register(typeof(ClassToMakeButtonFor2), new ButtonFactory2());
}
}
public class ButtonFactory2 : IAddButton {
public Button CreateButton() {
var b = new Button { Whatever = "Goodbye!" };
return b;
}
}
public static class ButtonFactory {
private static Dictionary<Type, IAddButton> FactoryMap = new Dictionary<Type, IAddButton>();
public static void Register(Type type, IAddButton factoryClass) {
FactoryMap[type] = factoryClass;
}
public static Button MakeMeAButton<T>() where T : class {
return FactoryMap[typeof(T)].CreateButton();
}
}
internal class Program {
private static void Main(string[] args) {
ClassToMakeButtonFor1.RegisterMe();
ClassToMakeButtonFor2.RegisterMe();
Button b = ButtonFactory.MakeMeAButton<ClassToMakeButtonFor1>();
Console.WriteLine(b.Whatever);
b = ButtonFactory.MakeMeAButton<ClassToMakeButtonFor2>();
Console.WriteLine(b.Whatever);
Console.ReadLine();
}
}
What you could consider is to have some interface (e.g. ICreator) that defines a Create method you want to call.
Then you would constrain your type parameter to types that implement the interface ( where T : ICreator).
Then you would call the method on an instance, not a static method. So in your case maybe you could call item.Create(...).
Makes any sense for your case?
It sounds like you might be able to make your Button class generic. Depending on how much logic lives in each of these derived classes, this may not work for you.
class Button<T>
{
public T Item { get; private set; }
public Button(string name, T item, ...)
{
// Constructor code
}
}
// Helper class for creation
static class Button
{
public static Button<T> Create<T>(string name, T item, ...)
{
return new Button<T>(name, item, ...);
}
}
Then, to use this:
Button<Company> button = Button.Create("Name", company, ...);
I have generic list of a custom class which has 2 properties. These properties store the raltionship between on form and another form. The list is structured as a hierachical list (parent / child ) relationship. What I want to be able to do is get a list of all forms based on a parent form reference which will be passed to a function. I am thinking the best way to go about this is with a LINQ query using a recursive approach. I am sure someone can point me in the right direction
This is the class used in the list
class FormStack {
#region Declares
private Form _form;
private Form _parent;
#endregion
#region Constructor
static FormStack()
{
}
#endregion
public Form Form
{
get { return _form; }
set { _form = value; }
}
public Form Parent
{
get { return _parent; }
set { _parent = value; }
}
}
So I would like to be able to Call a method and pass a form reference to the function and get all the children form related to this parent.
This is some of the code I have been stumbling with
// create a lookup list
var list = formStack.ToLookup( p => object.ReferenceEquals( p.Parent, parent ) );
// create a function
Func<IEnumerable<Form>, IEnumerable<Form>> recurse = null;
recurse = qs =>
{
return
qs
.Concat(
from q in qs
from q2 in recurse( list[] )
select q2 );
};
// filter the list
var children = recurse( list[parent] ).ToList();
I have a winform application which has standard CRUD functionality. Lets say there is a list of customers and each customer can have multiple address and each one of these addresses have multiple buildings, the way I have structured the forms is there is a list of customers, from this list you can open a detail form for a particular customer. This form has the details of the customer and all the addresses in a list. This list allows the user to now selected an address in the list and open the address details form which has a list of buildings and so on.... My problem is I want to close the customer detail and all the related forms for this customer. My idea was to keep of the relationship between the forms, but maybe I there is a better way???
here is what I made up:
Create a base Form for all your Forms:
public class MyFormBase : Form
{
public MyFormBase()
{
FormRepository.RegisterForm(this);
}
public MyFormBase(MyFormBase parent)
: this()
{
Parent = parent;
}
public MyFormBase Parent { get; set; }
}
Each Form can only have one Parent that is passed in the constuctor.
Create a Repository (or something simiar) to store your forms -> I do not want to store all children in the Form itself
//infrastructure - simulated with a static class
public static class FormRepository
{
private static List<MyFormBase> _allForms = new List<MyFormBase>();
public static void RegisterForm(MyFormBase form)
{
_allForms.Add(form);
}
public static void CloseFormAndChildren(MyFormBase form)
{
_allForms.Where(x => x.Parent.Equals(form)).ToList().ForEach(x => CloseFormAndChildren(x));
form.Close();
}
}
Call CloseFormAndChildren on any form you want to close (including the children). This could be called in the closing event...
Okay, it sounds to me like you have two issues. One is a syntax error (recurse(list[]) is wrong), but the other is that your FormStack isn't really a stack. It's just two forms, with no way to create a recursive chain. I think you want this:
public class FormStack : IEnumerable<Form> // or just implement SelectMany
{
public Form Form { get; set; }
public FormStack Parent { get; set; }
//implement IEnumerable<Form> or the SelectMany method
}
Then I think you can just do this, but it seems like an awkward thing to do:
Func<FormStack, IEnumerable<Form>> recurse = qs =>
{
return from q in qs
select (new[] { qs.Form }).Concat(recurse(qs.Parent));
};
var list = recurse(formStack).ToList();
That's if you're insisting on the query syntax.
If I were you, though, I'd forget all that and implement an IEnumerator<Form> to do it all for you:
public class FormStack : IEnumerable<Form>
{
public Form Form { get; set; }
public FormStack Parent { get; set; }
public IEnumerator IEnumerable:GetEnumerator()
{
return (IEnumerator)GetEnumerator();
}
public IEnumerator<Form> GetEnumerator()
{
return new FormStackEnumerator(this);
}
}
public class FormStackEnumerator : IEnumerator<Form>
{
private FormStack _stack;
private FormStack _first;
public Form Current { get { return _stack.Form; } }
object IEnumerator.Current { get { return Current; } }
public FormStackEnumerator(FormStack stack)
{
_stack = stack;
_first = stack;
}
public bool MoveNext()
{
if (_stack.Parent == null)
{
return false;
}
_stack = _stack.Parent;
return true;
}
public void Reset() { _stack = _first; }
void IDisposable.Dispose() { }
}
Then all you'd need to do in your main code is this:
var list = new List<Form>();
foreach (var node in formStack)
{
list.Add(node.Form);
}
By the way, I just looked up the Form class (I'm not a WinForms developer) and the Forms themselves have a Parent member. So you don't really need to wrap them in a node-type construct; they're already nodes! That makes everything easy:
var list = new List<Form>();
Action<Control> recurse = target =>
{
var form = target as Form;
if (form != null)
{
list.Add(form);
recurse(target.Parent);
}
}