Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I use the following to create and init some of the classes that need default and shared behaviour. Maybe if you can refactor it will help:</p> <p>It is some form of the <a href="http://en.wikipedia.org/wiki/Factory_method_pattern" rel="nofollow">Factory</a> and <a href="http://en.wikipedia.org/wiki/Flyweight_pattern" rel="nofollow">FlyWeight</a> patterns combined (the flyweight part can be removed in your scenario), which in addition has a concept of class Type shared handlers.</p> <p>I simplified and removed some stuff that you wont need but there is more to remove, I added comments.</p> <p>Usage would be: (app init)</p> <pre><code>Dictionary&lt;int,int&gt; vacationWeeksTable = new Dictionary&lt;int,int&gt;(); // fill the table Factory&lt;Employee&gt;.Init(vacationWeeksTable); </code></pre> <p>The whenever you create a Employee class:</p> <pre><code>// remove grouping in the factory class to remove this null Employee em = Factory&lt;Employee&gt;.Create(null); </code></pre> <p>It takes only a WeakReference to the classes so you don't have to worry about GC.</p> <p>Each employee will have the shared vacationWeeksTable setup on creation, without the possibility to change it after from outside if not using the factory class.</p> <p>You could change the vacation table for all running instances of Employee at any moment in the runtime of the app with:</p> <pre><code>// this will call the method registered for SetInitialdata on all instances of Employee classes. // again remove grouping to remove that null Factory&lt;Employee&gt;.Call(EventHandlerTypes.SetInitialData, null, vacTable); </code></pre> <p>Sample implementation of Employee:</p> <pre><code>class Employee : IBaseClass { private Dictionary&lt;int, int&gt; vacationWeeksTable; public virtual void RegisterSharedHandlers(int? group, Action&lt;IKey, int?, EventHandlerTypes, Action&lt;object, SharedEventArgs&gt;&gt; register) { group = 0; // disable different groups register(new Key&lt;Employee, int&gt;(0), group, EventHandlerTypes.SetInitialData, SetVacationWeeksTable); } public virtual void RegisterSharedData(Action&lt;IKey, object&gt; regData) { // remove this from factory and interface, you probably dont need it // I have been using it as a FlyWeight data store for classes. } private void SetVacationWeeksTable(object sender, SharedEventArgs e) { vacationWeeksTable = e.GetData&lt;Dictionary&lt;int, int&gt;&gt;(); } } </code></pre> <p><strong>Code pattern Implementation:</strong></p> <p>IBaseClass : interface that each of my classes that are creatable through a factory implement</p> <pre><code>public enum EventHandlerTypes { SetInitialData // you can add additional shared handlers here and Factory&lt;C&gt;.Call - it. } public class SharedEventArgs : EventArgs { private object data; public SharedEventArgs(object data) { this.data = data; } public T GetData&lt;T&gt;() { return (T)data; } } public interface IBaseClass { void RegisterSharedHandlers(int? group, Action&lt;IKey, int?, EventHandlerTypes, Action&lt;object, SharedEventArgs&gt;&gt; regEvent); void RegisterSharedData(Action&lt;IKey, object&gt; regData); } </code></pre> <p>Utility generic classes:</p> <pre><code>public interface IKey { Type GetKeyType(); V GetValue&lt;V&gt;(); } public class Key&lt;T, V&gt; : IKey { public V ID { get; set; } public Key(V id) { ID = id; } public Type GetKeyType() { return typeof(T); } public Tp GetValue&lt;Tp&gt;() { return (Tp)(object)ID; } } public class Triple&lt;T, V, Z&gt; { public T First { get; set; } public V Second { get; set; } public Z Third { get; set; } public Triple(T first, V second, Z third) { First = first; Second = second; Third = third; } } </code></pre> <p>Factory class with slight modification to handle your scenario:</p> <pre><code> public static class Factory&lt;C&gt; where C : IBaseClass, new() { private static object initialData; private static Dictionary&lt;IKey, Triple&lt;EventHandlerTypes, int, WeakReference&gt;&gt; handlers = new Dictionary&lt;IKey, Triple&lt;EventHandlerTypes, int, WeakReference&gt;&gt;(); private static Dictionary&lt;IKey, object&gt; data = new Dictionary&lt;IKey, object&gt;(); static Factory() { C newClass = new C(); newClass.RegisterSharedData(registerSharedData); } public static void Init&lt;IT&gt;(IT initData) { initialData = initData; } public static Dt[] GetData&lt;Dt&gt;() { var dataList = from d in data where d.Key.GetKeyType() == typeof(Dt) select d.Value; return dataList.Cast&lt;Dt&gt;().ToArray(); } private static void registerSharedData(IKey key, object value) { data.Add(key, value); } public static C Create(int? group) { C newClass = new C(); newClass.RegisterSharedHandlers(group, registerSharedHandlers); // this is a bit bad here since it will call it on all instances // it would be better if you can call this from outside after creating all the classes Factory&lt;C&gt;.Call(EventHandlerTypes.SetInitialData, null, initialData); return newClass; } private static void registerSharedHandlers(IKey subscriber, int? group, EventHandlerTypes type, Action&lt;object, SharedEventArgs&gt; handler) { handlers.Add(subscriber, new Triple&lt;EventHandlerTypes, int, WeakReference&gt;(type, group ?? -1, new WeakReference(handler))); } public static void Call&lt;N&gt;(EventHandlerTypes type, int? group, N data) { Call&lt;N&gt;(null, type, group, data); } public static void Call&lt;N&gt;(object sender, EventHandlerTypes type, int? group, N data) { lock (handlers) { var invalid = from h in handlers where h.Value.Third.Target == null select h.Key; // delete expired references foreach (var inv in invalid.ToList()) handlers.Remove(inv); var events = from h in handlers where h.Value.First == type &amp;&amp; (!@group.HasValue || h.Value.Second == (int)@group) select h.Value.Third; foreach (var ev in events.ToList()) { // call the handler ((Action&lt;object, SharedEventArgs&gt;)ev.Target)(sender, arg); } } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload