I have Singleton class that get's data from web. And i need to pass those data to classes FirstDerived and SecondDerived. In this case is my class Singleton anti-pattern? Is it normal to use Aggregation relationship between DataSocket and FirstDerived, SecondDerived. Maybe it exist better object oriented solution?
namespace WpfApplication
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new TestViewModel();
}
}
public class TestViewModel
{
public ObservableCollection<Base> Items { get; set; }
public TestViewModel()
{
DataSocket.Instance.SendDataAsync();
Items = new ObservableCollection<Base>();
Items.Add(new FirstDerived(1, DataSocket.Instance));
Items.Add(new SecondDerived(2, DataSocket.Instance));
}
}
public abstract class Base
{
}
public class FirstDerived : Base, IDisposable
{
public FirstDerived(int id, DataSocket socket)
{
socket.Client += ProcessDataFromSocket;
}
public void ProcessDataFromSocket(string arg)
{
Console.WriteLine("First Derived getting data: {0}", arg.ToString());
}
public void Dispose()
{
throw new NotImplementedException();
}
}
public class SecondDerived : Base, IDisposable
{
public SecondDerived(int id, DataSocket socket)
{
DataSocket.Instance.Client += ProcessDataFromSocket;
}
public void ProcessDataFromSocket(string arg)
{
Console.WriteLine("Second Derived getting data: {0}", arg.ToString());
}
public void Dispose()
{
throw new NotImplementedException();
}
}
public sealed class DataSocket
{
private static DataSocket instance;
public delegate void Messages(string info);
public event Messages Client;
private DataSocket()
{
}
public void SendDataAsync()
{
Action Send = new Action(SendData);
IAsyncResult result = Send.BeginInvoke(null,null);
}
public void SendData()
{
while(true)
{
if (Client != null)
{
System.Threading.Thread.Sleep(3000);
Client("Test");
}
}
}
public static DataSocket Instance
{
get
{
if (instance==null)
{
instance = new DataSocket();
}
return instance;
}
}
}
}
To me it looks like DataSocket is the class that deals with networking, so any code to interact with the network should go there. Don't pass it into a constructor.
Rather, do something more like this sequence;
DataSocket.Instance.SendDataAsync();
Items = new ObservableCollection<Base>();
var data1 = await DataSocket.ReadData();
var data2 = await DataSocket.ReadData();
Items.Add(new FirstDerived(1, data1));
Items.Add(new SecondDerived(2, data2));
This way, your classes don't take a dependency on a global, constantly-changing object.
You might also want to consider some kind of lock statement to make sure that different parts of the code -- say, many different simultaneous web requests -- can't interfere with each other.
Related
A state machine for war chess.
I want to make events such as moving (button and mouse dragging) and releasing skills into states.
Other chess will grasp the reality and do their work.
I didn't use event binding because I need to decide the execution order, from near to distance.
My current code looks like this, types as interface members.
It works, but it feels very strange to use.
public abstract class PlayerState : IState<PlayerState>
{
private static PlayerStateMachine Machine = new PlayerStateMachine();
public IStateMachine<PlayerState> StateMachine => Machine;
public abstract void Enter(IState<PlayerState> state);
public abstract void Exit(IState<PlayerState> state);
}
public class PlayerStateMachine : MonoBehaviour, IStateMachine<PlayerState>
{
[SerializeField] private PlayerState[] States;
private void Awake()
{
foreach (var item in States)
{
IStateMachine<PlayerState>.Add(item);
}
}
}
public interface IResponse
{
public int Point { get; }
}
public partial interface IResponse<T> : IResponse where T : IResponse<T>.PlayerState
{
public void Response();
private static HashSet<IResponse> response = new HashSet<IResponse>();
public static void Add(IResponse response)
{
IResponse<T>.response.Add(response);
}
public static void Remove(IResponse response)
{
IResponse<T>.response.Remove(response);
}
public abstract class PlayerState : Player.PlayerState
{
protected HashSet<IResponse<T>> Response => response;
}
}
These are base classes.
The following is an example of using a base class.
internal class Idel : IResponse<Idel>.PlayerState
{
public override void Enter(IState<PlayerState> state) {
foreach (var item in Response.OrderBy(item=>item.Point))
{
item.Response();
}
}
public override void Exit(IState<PlayerState> state) => throw new NotImplementedException();
}
public class Magma : IResponse<Idel>, IResponse<Move>
{
int IResponse.Point => throw new NotImplementedException();
void IResponse<Move>.Response() => throw new NotImplementedException();//lost Hp
void IResponse<Idel>.Response() => throw new NotImplementedException();//lost Hp
}
I hope IResponse. Response() can only be accessed by "class Idel".
"class Move" can't work, neither can "class Magma"
For the state machine, the state should have priority. IResponse is only auxiliary.
But now you need to access the state from IResponse. It seems unreasonable.
I have a number of methods that are called on different 3rd party systems. I now have another 3rd party system that will have the same set of methods actioned against it. If both 3rd party systems are connected I will then call the methods on each object in turn.
Currently I have a class that I pass round that I can call the method once and it checks and then calls it on each system that is enabled, this has an instance of each objects classes, similar to this:
public class AACSCaller
{
3rdPartySystem1 _system1;
3rdPartySystem2 _system2;
public AACSCaller(Settings appSettings)
{
_appSettings = appSettings;
if (appSettings.system1Enabled)
{
_system1 = new 3rdPartySystem1();
}
if (appSettings.system2Enabled)
{
_system2 = new 3rdPartySystem2();
}
}
public void Method1()
{
if (appSettings.system1Enabled)
{
_system1.Method1();
}
if (appSettings.system2Enabled)
{
_system2.Method1();
}
}
public void Method2()
{
if (appSettings.system1Enabled)
{
_system1.Method2();
}
if (appSettings.system2Enabled)
{
_system2.Method2();
}
}
}
Is this sensible, as it does seem there maybe a better way and I may well be connecting additional system at some point.
A possible solution here is to define an interface or base class for 3rdPartySystem1 and 3rdPartySystem2 classes, store instances in a collection and call required methods for every item in collection. If only one system is enabled, you'll have only one item in collection, if both is enabled, you'll call them one by one in loop
public interface IThirdPartySystem
{
void Method1();
void Method2();
}
public class ThirdPartySystem1 : IThirdPartySystem
{
//implementation
}
public class ThirdPartySystem2 : IThirdPartySystem
{
//implementation
}
public class AACSCaller
{
IList<IThirdPartySystem> _systems = new List<IThirdPartySystem>();
public AACSCaller(Settings appSettings)
{
_appSettings = appSettings;
if (appSettings.system1Enabled)
{
_systems.Add(new ThirdPartySystem1());
}
if (appSettings.system2Enabled)
{
_systems.Add(new ThirdPartySystem2());
}
}
public void Method1()
{
foreach (var system in _systems)
system.Method1();
}
public void Method2()
{
foreach (var system in _systems)
system.Method2();
}
}
I suggest you to use interface that have Method1 and Method2 methods and then create to classes System1 and System2 that are implements the interface. Where AACSCaller is create you initialize the correct implementation of the interface and in your methods your just Call to the correct instance method without conditions.
public class AACSCaller
{
IThirdPartySystem ThirdPartySystem;
public AACSCaller(Settings appSettings)
{
_appSettings = appSettings;
ThirdPartySystem = appSettings.system1Enabled ? new ThirdPartySystem1() : new ThirdPartySystem2();
}
public void Method1() => ThirdPartySystem.Method1();
public void Method2() => ThirdPartySystem.Method2();
}
public interface IThirdPartySystem
{
void Method1();
void Method2();
}
public class ThirdPartySystem1 : IThirdPartySystem
{
public void Method1()
{
//code here..
}
public void Method2()
{
//code here..
}
}
public class ThirdPartySystem2 : IThirdPartySystem
{
public void Method1()
{
//code here..
}
public void Method2()
{
//code here..
}
}
I have a question about disposing objects.
Consider this IDisposable class
public class MyClass : DisposableParentClass
{
private MyProp _prop;
public MyClass(MyProp prop)
{
_prop = prop;
}
public MyClass()
{
_prop = new MyProp();
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
_prop.Dispose();
}
base.Dispose(disposing);
}
}
On the first constructor, MyProp is injected. So MyClass is not the owner of the object. But on the second constructor, MyProp is created locally.
Should I always dispose MyProp, or should I check first if it is injected or not.
public class MyClass : DisposableParentClass
{
private MyProp _prop;
private bool _myPropInjected = false;
public MyClass(MyProp prop)
{
_prop = prop;
_myPropInjected = true;
}
public MyClass()
{
_prop = new MyProp();
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (!_myPropInjected) { _prop.Dispose(); }
}
base.Dispose(disposing);
}
}
If your class should handle these two situations:
It is not the owner of the provided object, it should not dispose of it
It is the owner of the created object, it should dispose of it
Then yes, you need to have a mechanism that tells these two situations apart.
A common method (common to me anyway) is to use naming convention like this:
private MyProp _prop;
private bool _ownsProp = false;
ie. reverse the meaning of your flags, but this is details, your solution is just fine, and yes, you need to have a solution like this.
If you have a ton of these fields, where each must have its own bool field to handle this, it might be worth creating a helper class, such as this LINQPad program demonstrates:
void Main()
{
Injectable i1 = new Injectable();
Injectable i2 = new Injectable(new Injected("A"));
Injectable i3 = new Injectable(new Injected("A"), new Injected("B"));
Debug.WriteLine("dispose a and b");
i1.Dispose();
Debug.WriteLine("dispose b");
i2.Dispose();
Debug.WriteLine("no dispose");
i3.Dispose();
}
public class Injected : IDisposable
{
public Injected(string name) { Name = name; }
public string Name { get; set; }
public void Dispose() { Debug.WriteLine(Name + " disposed"); }
}
public class Injectable : IDisposable
{
private Ownable<Injected> _A;
private Ownable<Injected> _B;
public Injectable(Injected a, Injected b)
{
_A = Ownable.NotOwned(a);
_B = Ownable.NotOwned(b);
}
public Injectable(Injected a)
{
_A = Ownable.NotOwned(a);
_B = Ownable.Owned(new Injected("B"));
}
public Injectable()
{
_A = Ownable.Owned(new Injected("A"));
_B = Ownable.Owned(new Injected("B"));
}
public void Dispose()
{
_A.Dispose();
_B.Dispose();
}
}
public class Ownable<T> : IDisposable
where T : class
{
private readonly T _Instance;
private readonly Action _CleanupAction;
public Ownable(T instance, bool isOwned)
{
_Instance = instance;
if (isOwned)
{
IDisposable disposable = instance as IDisposable;
if (disposable == null)
throw new NotSupportedException("Unable to clean up owned object, does not implement IDisposable");
_CleanupAction = () => disposable.Dispose();
}
}
public Ownable(T instance, Action cleanupAction)
{
_Instance = instance;
_CleanupAction = cleanupAction;
}
public T Instance { get { return _Instance; } }
public void Dispose()
{
if (_CleanupAction != null)
_CleanupAction();
}
}
public static class Ownable
{
public static Ownable<T> Owned<T>(T instance)
where T : class
{
return new Ownable<T>(instance, true);
}
public static Ownable<T> Owned<T>(T instance, Action cleanupAction)
where T : class
{
return new Ownable<T>(instance, cleanupAction);
}
public static Ownable<T> NotOwned<T>(T instance)
where T : class
{
return new Ownable<T>(instance, false);
}
}
A different note can be made here either.
It depends on what is your MyClass is doing actually.
For example, if we are talking about a class that reads video stream from device, after applies some filters to it and writes data to a user specified file, where file writing is made by stream passed from the outside, say like this:
public class VideoProcessor : IDisposable {
private FileStream _videoFile = null;
private VideoProcessor() {}
//user specified FileStream
public VideoProcessor(FileStream fs) {_videoFile = fs;}
public void Dispose() {
_videoFile.Dispose(); //Dispose user passed FileStream
}
}
disposing passed stream object during dispose call, makes actually sence.
In other cases, yes, it's better to not destroy object, if you are not an owner of it. Leave it to the caller to decide when it is appropriate time to do that.
We are using factory to create an instance of Subscribers. Each subscriber can have its own dependency.
Each subscriber will use constructor injection.
Should I pass dependency into subscribers through Subscriber Factory? Every time adding new dependency in any subscriber will change Subscriber factory?
public interface IMessageSubscriber
{
bool Process(string message)
}
public class MessageSubscriber1 : IMessageSubscriber
{
public bool Process(string message)
{
//Some custom logic
}
}
public class MessageSubscriber2 : IMessageSubscriber
{
public bool Process(string message)
{
//Some custom logic
}
}
public class MessageSubscriberFactory
{
//SubscriberType is enum
public IMessageSubscriber Get(SubscriberType type)
{
if(type == 1)
{
return new MessageSubscriber1();
}
else if(type == 2)
{
return new MessageSubscriber2();
}
}
}
//Main class
public class Process
{
public static void Main(string[] args)
{
MessageSubscriberFactory fac = new MessageSubscriberFactory();
foreach SubscriberType
{
string = "Message";
IMessageSubscriber subscriber = fac.Get(type);
subscriber.Process(message)
}
}
}
One approach would be to use named registrations with a DI/IOC container. This would involve using the container in a service locator fashion (which some people oppose), but I think it could make sense in this case. The example below is pretty crude, but it does give you an approach to handle subscribers with different dependencies without passing them into the factory. I used Unity here and you'd want to wrap the container reference rather than referencing directly, but this gets the point across.
public interface ILowerCaseWriter
{
void Write(string message);
}
public class LowerCaseWriter : ILowerCaseWriter
{
public void Write(string message)
{
Console.WriteLine(message.ToLower());
}
}
public interface IUpperCaseWriter
{
void Write(string message, int number);
}
public class UpperCaseWriter : IUpperCaseWriter
{
public void Write(string message, int number)
{
Console.WriteLine("{0}:{1}", number, message.ToUpper());
}
}
public interface ISubscriber
{
void Write();
}
public class Subscriber1 : ISubscriber
{
private ILowerCaseWriter _writer;
public Subscriber1(ILowerCaseWriter writer)
{
_writer = writer;
}
public void Write()
{
_writer.Write("Using subscriber 1");
}
}
public class Subscriber2 : ISubscriber
{
private IUpperCaseWriter _writer;
public Subscriber2(IUpperCaseWriter writer)
{
_writer = writer;
}
public void Write()
{
_writer.Write("Using subscriber 2", 2);
}
}
public class SubscriberFactory
{
private UnityContainer _container;
public SubscriberFactory()
{
_container = new UnityContainer();
_container.RegisterType<ILowerCaseWriter, LowerCaseWriter>();
_container.RegisterType<IUpperCaseWriter, UpperCaseWriter>();
_container.RegisterType<ISubscriber, Subscriber1>("Subscriber1");
_container.RegisterType<ISubscriber, Subscriber2>("Subscriber2");
}
public ISubscriber GetSubscriber(int type)
{
switch (type)
{
case 1:
return _container.Resolve<ISubscriber>("Subscriber1");
case 2:
return _container.Resolve<ISubscriber>("Subscriber2");
default:
throw new Exception();
}
}
}
class Program
{
private static void Main(string[] args)
{
var factory = new SubscriberFactory();
var subscriber = factory.GetSubscriber(1);
subscriber.Write();
Console.ReadLine();
}
}
I'm trying out an example of using Domain Events to notify of when something has happened in a system (borrowed from here and here).
I'm really close to getting the code working how I want, however, I've hit a bit of a brick wall. Here is my DomainEvents class:
public static class DomainEvents
{
[ThreadStatic]
private static IList<IEventHandler<IDomainEvent>> Actions;
public static void Register<T>(IEventHandler<T> callback) where T : IDomainEvent
{
if (Actions == null)
{
Actions = new List<IEventHandler<IDomainEvent>>();
}
Actions.Add(callback); // <---- Problem here, since I can't add callback to the collection.
}
public static void ClearCallbacks()
{
Actions = null;
}
public static void Raise<T>(T args) where T : IDomainEvent
{
if (Actions == null)
{
return;
}
foreach (var action in Actions)
{
if (action is IEventHandler<T>)
{
((IEventHandler<T>)action).Handle(args);
}
}
}
The above won't compile because Actions.Add cannot accept callback since it's a IEventHandler<T> type rather then a IEventHandler<IDomainEvent> type. Here's some more code to clarify.
This is called from my console application:
DomainEvents.Register(new CustomerHasUnpaidDuesEventHandler());
CustomerHasUnpaidDuesEventHandler implements IEventHandler<CustomerHasUnpaidDuesEvent>, where CustomerHasUnpaidDuesEvent implements IDomainEvent.
public class CustomerHasUnpaidDuesEventHandler : IEventHandler<CustomerHasUnpaidDuesEvent>
{
public IEmailSender EmailSender { get; set; }
public void Handle(CustomerHasUnpaidDuesEvent #event)
{
this.EmailSender.SendEmail(#event.Customer.EmailAddress);
}
}
public class CustomerHasUnpaidDuesEvent : IDomainEvent
{
public CustomerHasUnpaidDuesEvent(Customer customer)
{
this.Customer = customer;
}
public Customer Customer { get; set; }
}
This is what I don't get - if CustomerHasUnpaidDuesEvent implements IDomainEvent, then why is the call to Actions.Add failing? How can I resolve this?
EDIT:
To make things clearer, here is entire code for my test app:
class Program
{
static void Main()
{
DomainEvents.Register(new CustomerHasUnpaidDuesEventHandler());
var c = new Customer();
c.EmailAddress = "test#dfsdf.com";
c.CheckUnpaidDues();
}
}
public interface IEventHandler<in T> where T : IDomainEvent
{
void Handle(T args);
}
public interface IEmailSender
{
void SendEmail(string emailAddress);
}
public interface IDomainEvent
{
}
public static class DomainEvents
{
[ThreadStatic]
private static IList<IEventHandler<IDomainEvent>> Actions;
public static void Register<T>(IEventHandler<T> callback) where T: IDomainEvent
{
if (Actions == null)
{
Actions = new List<IEventHandler<IDomainEvent>>();
}
Actions.Add(callback);
}
public static void ClearCallbacks()
{
Actions = null;
}
public static void Raise<T>(T args) where T : IDomainEvent
{
if (Actions == null)
{
return;
}
foreach (IEventHandler<T> action in Actions)
{
(action).Handle(args);
}
}
}
public class CustomerHasUnpaidDuesEventHandler : IEventHandler<CustomerHasUnpaidDuesEvent>
{
public IEmailSender EmailSender { get; set; }
public void Handle(CustomerHasUnpaidDuesEvent #event)
{
this.EmailSender.SendEmail(#event.Customer.EmailAddress);
}
}
public class CustomerHasUnpaidDuesEvent : IDomainEvent
{
public CustomerHasUnpaidDuesEvent(Customer customer)
{
this.Customer = customer;
}
public Customer Customer { get; set; }
}
public class Customer
{
public string Name { get; set; }
public string EmailAddress { get; set; }
public bool HasUnpaidDues { get; set; }
public void CheckUnpaidDues()
{
HasUnpaidDues = true;
DomainEvents.Raise(new CustomerHasUnpaidDuesEvent(this));
}
}
Cheers.
Jas.
There is no need for your Register method to be generic:
public static void Register(IEventHandler<IDomainEvent> callback)
{
if (Actions == null)
{
Actions = new List<IEventHandler<IDomainEvent>>();
}
Actions.Add(callback);
}
Edit:
The problem is that in order to have IEventHandler<CustomerHasUnpaidDuesEvent> to be in the list of IEventHandler<IDomainEvent>s, we need T to be a covariant template parameter in IEventHandler<T> (which is declared as IEventHandler<out T>). However in order to allow the function Handle(T arg), we need T to be contravariant. So strictly this way won't work. Imagine: if we really could insert an IEventHandler<CustomerHasUnpaidDuesEvent> into a list of IEventHandler<IDomainEvent>s, than someone might try to call Handle with the argument of some type which derives from IDomainEvent but is not a CustomerHasUnpaidDuesEvent! This should be impossible to do.
The solution is that we don't need the exact type at Register, so we can keep a reference to a generic base interface. The implementation is here: http://ideone.com/9glmQ
Old answer is not valid, kept below for consistency.
Maybe you need to declare IEventHandler to accept T as a covariant type?
interface IEventHandler<in T> where T: IDomainEvent
{
void Handle();
// ...
}
Edit: surely CustomerHasUnpaidDuesEvent is an IDomainEvent, but you need IEventHandler<CustomerHasUnpaidDuesEvent> to be a IEventHandler<IDomainEvent>. This is exactly what covariance does. In order to allow that, your template parameter in IEventhandler must be declared covariant (<in T> instead of just <T>).