I have a class that instantiates two classes which implement interfaces. I want one class to notify another class that something is OK. I could do it with an Action and then use private variables in the class but wondered if there was a direct way of doing it with properties so that when a property's value changes it updates a property on another class.
For example:
public class MyClass
{
public ILogger Logger {get;set;}
public ILogic Logic {get;set;}
private Form MyWinform;
public void Setup()
{
MyWinform = new MyWinform();
MyWinform.StartBatch += Logger.CreateFile; //Create file when user presses start
//How can I set a property on ILogic to be AllOk once ILogger says so??
//I could use an Action so that once all is ok I call IDecidedAlOK in ILogger which
//can then assign a private bool variable inside the class
Logic.ItsOKMethodSoSetVariableToTrue = Logger.IDecidedAllOKMethod;
}
public void DataIn(string Value)
{
Logic.DataIn(Value);
}
public void CreateInstances()
{
Logger = new FileLogger();
Logic = new MyLogic();
}
}
public class MyLogic : ILogic
{
public void DataIn(string Value)
{
//I want to check that all is ok before I do anything
//if (!AllOK)
//return;
//Do stuff
}
}
Implement INotifyPropertyChanged interface and subscribe to PropertyChanged event
I feel like it might be a bit more conventional to have your ILogger interface expose something like a "FileCreated" or "Ready" event, and allow your application to handle that event in order to update the ILogic object (or do whatever else is necessary).
EDIT: my apologies, after re-reading the question, I think I misunderstood what you were asking for.
There isn't any "natural" object that does exactly what you're asking, but you could create an anonymous delegate (or lambda expression) for this purpose:
Action<bool> loggerResult = (value) => Logic.ItsOKMethodSoSetVariableToTrue = value;
A property internally consists of two private methods, a get_XXX and a set_XXX, so unless you want to fetch the MethodInfo of those methods and invoke them (which are again methods) you have no choice but to implement a method calling approach.
Subscribing to event (INotifyPropertyChanged or some custom one) is OK, so is the method to pass a lambda-setter, but in some cases it might be more convinient to use a shared context object (much like the shared memory concept):
class ConversationContext
{
public bool EverythingIsOK { get; set;}
}
This object is passed to all interested objects (ILogic and ILogger) and they operate directly on it, instead of some internal properties. If change notifications are required, Implement INotifyPropertyChanged on it.
One positive aspect of this approach is that you won't get tangled in repeatedly firing events triggering other events and so on. A single object will hold the current state and no recurrent updates are needed.
Again, this is just one of many options.
Related
While I was looking at some c# code I found a new class declaration which had passed a method as a constructor’s parameter.This is my first time I have seen something like this and it has no meaning for me .Although the whole application works fine I am still interested to know what is the main idea behind the scene.
var c = new List<TheClass>
{
new TheClass(TheMethod);
}
private void TheMethod()
{
//do somthing
}
I guess the TheClass constructor accepts an Action delegate:
public class TheClass
{
private readonly Action _action;
public TheClass(Action action)
{
_action = action;
}
}
This way TheClass can execute the provided action at a later time, and more than once.
For example:
public void DoAction()
{
_action();
}
You could also do:
var theClass = new TheClass(() => TheMethod());
There are many reasons that you might want to pass a method into the constructor of a class.
One of the most important is for so-called Dependency Injection, where want to inject a dependency into a class.
Suppose that a class needs to create an object. Normally, that class would do something like var item = new MyConcreteClass();.
However, that creates a strong dependency between the class creating the object and MyConcreteClass. This can make it harder to unit test or change implementations.
To circumvent this problem, you can do this:
Extract from MyConcreteClass an interface (say IMyInterface) which contains all the things you need to use from inside the class being written.
Pass to the class constructor a Func method which creates and returns a concrete class as IMyInterface.
Inside the class being written, call that Func to create the object rather than creating it directly using new.
The Func is therefore acting as a factory.
Code might look like this:
using System;
namespace Spacelabs.WcfDuplexDemo.Client
{
static class Program
{
static void Main()
{
var myClass = new MyClass(() => new MyConcreteClass());
myClass.DoSomething();
}
}
public interface IMyInterface
{
string MyMethod(int param);
}
public sealed class MyConcreteClass : IMyInterface
{
public string MyMethod(int param)
{
return param.ToString();
}
}
public sealed class MyClass
{
private readonly Func<IMyInterface> createMyInterface;
public MyClass(Func<IMyInterface> createMyInterface)
{
this.createMyInterface = createMyInterface;
}
public void DoSomething()
{
// Instead of var item = new MyConcreteClass(), we do the following:
var item = createMyInterface();
Console.WriteLine(item.MyMethod(12345));
}
}
The main idea is to defer execution of the method and control when it gets executed.
One use case for this is passing a method that creates and object so that the class controls when the object is created and it can control how many times it is created.
Are you unclear of why a method is being passed as an argument or specificly as an argument in a constructor?
CodeCaster already spoke short about Action delegates and if you're interested in storing methods in delegates like Action, I suggest you read up on Delegates here
I'd like to provide a short example of a class that contains an Action delegate: RelayCommand -> I've illustrated the use of this delegate with the MVVM pattern below:
class ViewModelDefault : INotifyPropertyChanged
{
public string TextProperty { get; set;}
public ICommand ButtonProperty
{
get {
RelayCommand relayCommand = new RelayCommand(ExecuteCommand);
return relayCommand;
}
}
private void ExecuteCommand()
{
HandlerClass handler = new HandlerClass();
handler.SaveTextInTextfile(TextboxProperty);
}
...
}
In the MVVM pattern, your main focus is to seperate data, logic and view, which is why using Delegate is perfect in this scenario.
You'd normally want to bind a property such as a string from the ViewModel to a View UI Element such as a TextBox.
Making use of delegates, allows you to bind a method (which would otherwise not be bindable to a UI element) through an Action property.
In the example above, the method ExecuteCommand is stored in an action field inside the RelayCommand object. This is bindable to a UI element, and will execute the method once it's requested.
I'm writing a simple game in Unity, and learning C# on my own. Currently I'm doing first pass on the scoring system. I decided to do this with native c# events. So my first idea was to have the Score class responsible for counting/keeping player score. This class would receive events from objects implementing the IScoreable interface.
It would look something like this (example code):
public interface IScoreable {
event Action<IScoreable> Scored;
int Value { get; set; }
}
public class Score {
public void addScore(IScoreable scoreable) {
//do something with scoreable.Value
}
}
In theory, it's decent enough, but I had a problem with coupling:
With just the above code, Score needs to know about all possible objects that implement IScoreable, so it can subscribe to the Scored event. Considering there will be a lot of various objects implementing this interface - it may get instantiated from different parts of code, I don't see any "clean" way of doing this.
Another option would be, to have every IScoreable object register itself with Score object, but this again would create strong coupling. For example adding another player, and subsequently another Score instance, would require rewriting all classes implementing IScoreable)
Which leaves me with two alternatives (that I see). Create some kind of event manager/ aggregator. This option is now for me (subjectively speaking, I like how in c# events are strongly connected to class that defines them).
Another option, the one I'm leaning towards, is to use a static event for this. This would require a switch from interface to abstract class for IScoreable. Which could be a big deal with c# single inheritance, but in this case it isn't (Unity component based approach, discourages deep inheritance trees) I think it would fit this use case quite well.
public abstract class Scorable {
public static event Action<Scorable> Scored;
protected virtual void onScored() { if (Scored != null) Scored(this); }
public int Value { get; set; }
}
Score object would simply subscribe to Scored, and be done. Every class inheriting from Scoreable would call base.onScore when needed, and be done. No additional classes would be needed. Other than possibility of memory leak - if not careful I don't see downsides to this.
But since the use of static events seems to be discouraged, I have my doubts, maybe because of my inexperience I don't see a simple solution.
So the question... Is there a better (cleaner, simpler) solution to my problem? Would you advise against the use of static event in this case?
I think you have this backwards. Rather than have a Score object that knows about everything that can change the score, you should have all of your objects that might update the Score know about a single instance (a singleton) Score object.
Really simple case might be something like:
public class Score
{
public int TheScore { get; private set; }
public static _instance;
public static Instance // I'm using a static property, but you could also create a static "getInstance" method if you prefer
{
get
{
if (_instance == null)
{
// Note: if you are multithreading, you might need some locking here to avoid ending up with more than one instance
_instance = new Score();
}
return _instance;
}
}
private Score()
{
// Note: it's important to have a private constructor so there is no way to make another instance of this object
}
public int AddToScore(int score)
{
// again - if you have multiple threads here you might need to be careful
TheScore += score;
}
}
Now in your object that might update the score, you just:
Score.Instance.AddToScore(100); // adds 100 to the score
Now if you want to get really fancy here, you could abstract the Score class into an interface IScore and then use an inversion of control (IoC) container to manage it for you. That way you can decouple the implementation of the class that holds the score from the classes that will consume it.
And of course to get the current score:
int currentScore = Score.Instance.TheScore;
If you want to use events, then you could look at the publisher/subscriber pattern where you'd basically have a singleton that acts as the manager for your events and everybody that need to publish an event (i.e. your Player class) will publish to it and your Score class will subscribe to it.
Here are a few changes that will give you much smoother coupling
public interface IScoreable {
event EventHandler<IScoreable> Scored;
int Value { get; set; }
}
Create a new ScoreEventArgs class to handle your event args in a more flexible way
public class ScoreEventArgs: EventArgs
{
public int Score {get;set;}
// Can put more properties here to include when the event is raised
public ScoreEventArgs(int value)
{
this.Score=value;
}
}
Changes to your abstract class to ensure that event is handled according to your needs
public abstract class Scorable {
event EventHandler<ScoreEventArgs> scored;
public event EventHandler<ScoreEventArgs> Scored;
{
add { this.scored += value; }
remove { this.Scored -= value; }
}
// onScored method now handles the object (could be player in your case) where its called from and the score
protected virtual void onScored(IScorable sender,int score)
{
if (Scored != null)
{
var e = new ScoreEventArgs(score)
Scored(sender,e);
// Could set optional this.Value += score; // to get the current score or something like that
}
}
public int Value { get; set; }
}
Your calling class which will implement the event and will have a score
public class Player : Scorable
{
public Player()
{
// Also can register a scored event callback
Scored+= new EventHandler<ScoreEventArgs>(PlayerScored);
}
private void PlayerScored(object sender, ScoreEventArgs args)
{
// Other logic can go here as well, this method will be called after the onScored(this, e) is called from the PlayerScored method.. You can update your UI or do other stuff here
}
public event EventHandler<ScoreEventArgs> Scored
{
add {this.Scored+=value;}
remove {this.Scored += value;}
}
private void PlayerScored()
{
// Raise the on scored event
onScored(this, new ScoreEventArgs(10));
}
}
Hope this clears some ambiguities..
I am new to C# and programming in general and am trying to figure out how to use events. Previously I have been programming with ActionScript3, and there events are a special class that you inherit from if you want to create your own events, and then that event can be called by any other class.
With C# I have tried to do something similar, like so:
public class EventManager
{
public delegate void TempDelegate();
public static event TempDelegate eSomeEvent;
}
public class SomeOtherClass
{
//doing some stuff, then:
if (EventManager.eSomeEvent != null)
{
EventManager.eSomeEvent();
}
}
This gives me a compiler error CS0070: The event 'EventManager.eSomeEvent' can only appear on the left hand side of += or -= (except when used from within the type 'EventManager')
The information about this error over on the msdn indicates that I should use += instead of trying to call the event, but I don't really understand this. I'm not trying to subscribe anything from SomeOtherClass to the event delegate, I am just trying to call this event so that it starts executing those functions that are already subscribed to that event.
So is it possible to do it this way? If not, is it at all possible to call an event that is of one class, from another class? I simply wish to reuse certain events in my classes rather than creating many similar ones in multiple classes.
Any advice with this would be greatly appreciated!
You can wrap the event call in a public method and use that from your other classes.
public void OnSomeEvent()
{
var handler = eSomeEvent;
if (handler != null) handler(this, null);
}
However you might want to look at the design again, if you are really sure the event should be on a different class than the one triggering it.
Well, the typical solution is to put eSomeEvent invocation into the EventManager class
public class EventManager
{
public delegate void TempDelegate();
public static event TempDelegate eSomeEvent;
// Not thread safe as well as your code
// May be internal, not public is better (if SomeOtherClass is in the same namespace)
public static void PerformSomeEvent() {
if (!Object.ReferenceEquals(null, eSomeEvent))
eSomeEvent(); // <- You can do it here
}
}
public class SomeOtherClass
{
//doing some stuff, then:
EventManager.PerformSomeEvent();
}
I'm trying to create a class (in C#) that serves as an environment for my application.
I'm trying to make the class dynamic, and send it as a parameter to entities in my application. The problem is, that I want to be able to change the properties of this environment class (public setters), but at the same time I want the classes that receive the environment to be unable to use these setters.
I can't seem to find a good way to phrase my question (which I figure is a part of the reason I can't find anything like this on Google or msdn), but to put shortly, I want to create a class with setters that are public only for some of my objects and not for all.
I'm currently amusing the following idea:
Avoiding the public setters all together, and expose the private fields using event registration.
The class will register to events in a new third object (sent as a parameter to the constructor). The methods that will be registered by the environment are not much more then setters, and so triggering these events will "allow access" to the private fields.
I'd love some ideas (seeing as I feel that mine isn't all that great), or better yet some patterns I could make use of.
Thanks in advance
Isn't "internal" sufficient for what you need?
And you could move the setters into an interface as explicit implementation. Then they are hidden from the public interface and only accessible if you cast to the interface.
And if you want to make really sure that nobody else can call it you can add some parameter to these functions where you expect a certain token object which you only give to trusted classes.
void SetX(int value, object token)
{
if(token!=correctToken)
throw new ArgumentException("wrong token");
x=value;
}
You could create a proxy, and send that proxy to your entity classes.
class MyClass
{
public int MyProperty { get; set; }
}
class MyProxyClass
{
public MyProxyClass(MyClass myClass)
{
_myClass = myClass;
}
private MyClass _myClass;
public int MyProperty
{
get { return _myClass.MyProperty; }
}
}
You could try using Friend assemblies. That will allow only the assemblies you specify to have access to your privates (snicker).
Maybe i understood something not quite well, but i think Jon had a quite similar problem which he described here. Maybe this can help you.
How about
class Callee
{
public void SetX(TypeOfCaller caller, int value)
{
}
}
class TypeOfCaller
{
public void Do()
{
Callee instance;
//..
instance.SetX(this, 5);
}
}
Doing so; you can also use Visual Studio' Find References feature! In case you want multiple types of caller; you can either opt for class hierarchy or can simply have required overloads
Why not return clones of your protected objects instead of the actual objects? Solves the problem without adding any more complexity.
public class MyService
{
private List<MyObject> _protectedObjects = new List<MyObject>();
public MyObject GetItem(int id)
{
return (MyObject)_protectedObjects.First(i => i.Id == id).Clone();
}
}
public class MyObject : ICloneable
{
//[...]
public object Clone()
{
return MemberwiseClone();
}
}
So what I'm trying to do is call a single propertyWasSet() function when any property within a C# class is set (conversely, propertyWasGot() when it is get). I would also like to know which property's 'get' was invoked.
I would like to maintain a dictonary of properties that are 'set', and check upon the 'get' action if they have been set yet (and throw an error if it hasn't been).
I've be looking through msdn documentation for reflection, delegates, etc..., but I'm not entirely sure this is possible.
Is there a way to do this? or fire an event upon calling one of these functions that can be intercepted in a base class or something?
I wrote an interceptor the other week for Set which can easily be extended for Get, it uses RealProxy, which means your base class needs to derive off MarshalByRefObject.
Another fancy option is to have your class abstract, and use Reflection Emit to construct a concrete class that wraps up all the properties.
Also you could look at code generators to get around this or PostSharp...
Performance for this solution is not stellar, but it should be plenty fast for most UI binding. It could be improved by generating LCG methods for proxy invocation.
public interface IInterceptorNotifiable {
void OnPropertyChanged(string propertyName);
}
/// <summary>
/// A simple RealProxy based property interceptor
/// Will call OnPropertyChanged whenever and property on the child object is changed
/// </summary>
public class Interceptor<T> where T : MarshalByRefObject, IInterceptorNotifiable, new() {
class InterceptorProxy : RealProxy {
T proxy;
T target;
EventHandler<PropertyChangedEventArgs> OnPropertyChanged;
public InterceptorProxy(T target)
: base(typeof(T)) {
this.target = target;
}
public override object GetTransparentProxy() {
proxy = (T)base.GetTransparentProxy();
return proxy;
}
public override IMessage Invoke(IMessage msg) {
IMethodCallMessage call = msg as IMethodCallMessage;
if (call != null) {
var result = InvokeMethod(call);
if (call.MethodName.StartsWith("set_")) {
string propName = call.MethodName.Substring(4);
target.OnPropertyChanged(propName);
}
return result;
} else {
throw new NotSupportedException();
}
}
IMethodReturnMessage InvokeMethod(IMethodCallMessage callMsg) {
return RemotingServices.ExecuteMessage(target, callMsg);
}
}
public static T Create() {
var interceptor = new InterceptorProxy(new T());
return (T)interceptor.GetTransparentProxy();
}
private Interceptor() {
}
}
Usage:
class Foo : MarshalByRefObject, IInterceptorNotifiable {
public int PublicProp { get; set; }
public string lastPropertyChanged;
public void OnPropertyChanged(string propertyName) {
lastPropertyChanged = propertyName;
}
}
[Test]
public void TestPropertyInterception() {
var foo = Interceptor<Foo>.Create();
foo.PublicProp = 100;
Assert.AreEqual("PublicProp", foo.lastPropertyChanged);
}
}
You may want to look into PostSharp for this sort of task. It is designed to run on top of C# (or any .NET language for that matter) and has the benefit of not cluttering up your code with reflection in addition. In fact, I don't believe you could find a solution that purely uses C#/Reflection without manually adding code to each of your properties, so I would definitely recommend PostSharp as the way to go.
I think what you need is very similar to WPF dependency property system. You might want to look at its implementation. Anyhow, you can add the intercepting code to getter and setter of each property too.
There's nothing like this if you don't create it yourself.
The SET part of your request is very similar to WPF dependency property system.
But the GET part is such unusual that is missing even in the WPF dependency property system!