tags:

views:

147

answers:

5

Is there a way to create some sort of interface that only allows the object to be accessible through events?

+15  A: 

Can't you just define an interface with only events in it?

For instance:

interface IExample
{
    event EventHandler Event1;
    event EventHandler Event2;
}

class Obj : IExample
{
    public event EventHandler Event1;
    public event EventHandler Event2;
}

Usage:

IExample obj = new Obj();
obj.Event1 += Event1_Handler;
obj.Event2 += Event2_Handler;
Matt Breckon
+1 - OK, I didn't think about this solution. I was too stuck on the implementation.
James Black
+1. Good answer. Better than mine.
David Stratton
+2  A: 

Without further information, the best answer I have is that you would simply need to make sure that all of the members properties, functions, etc) are declared as private, except for the events, which would be public.

Although I have to admit, I'm stumped as to how this would eve be useful, and what would trigger a event if it's only accessible to it's events. It's like saying can you create a phone that you can't call, but can only hear the ring (the IncomingCall event).

David Stratton
I am sure that at some point in our careers many of us will be asked to design a 'phone that you cant call, but can only answer' by someone who doesn't realize that's basically what they are asking for. I have been.
instanceofTom
That's true. Good point.
David Stratton
About the phone analogy - a note from my own experience: All members (properties, events, methods, etc.) of all objects are always accessible at runtime no matter what the access modifier is set to (private, internal, protected, etc.) through .NET reflection techniques - System.Reflection.* classes and such.Once I found this out, I stopped worrying about trying to tie things down too tight through access modifiers because ultimately it's impossible, all things considered. Of course hiding members makes sense at compile time to enforce desired operating parameters.
John K
+1  A: 

A setup like this would expose only events to a client using the assembly:

interface ISomething {
   event EventHandler MyEvent;
}

internal class MyClass : ISomething {
  ... 
}

public ClassFactory {
  public ISomething GetClass(){ // factory method
    return new MyClass();
  }
}

Or, if you need to restrict the use of this class in its own library as well you can do this:

public class MyClass : ISomething {
  private MyClass(){} // private constructor
  public ISomething  GetClass(){ // factory method
    return new MyClass();
  }
}

Something like this may be combined with a singleton object if you just need to get its events as well, which can make sense if you simply want have a generic way to subscribe to that object's status events for example.

Egor
A: 

Be aware that any object to which a caller has access can have any of it's fields accessed through reflection.

If your question is focused on preventing people from accidentally invoking your object incorrectly, Matt B.'s answer is great.

If your question is focused on making it impossible for someone to maliciously access private fields of your object, that's not possible.

Eric J.
A: 

Yes - this is a very vague question... but it comes from wanting to be able to have interdependencies between objects for example in an mvc pattern:

Controller SomeController = new Controller(view);

Then inside the controller:

view.Background = "red"; //breaks pattern
view.OnClick += MyHandler; //fine

Inside that controller I would like to be able to restrict the access to the view to things that happen... explicitly saying: You cannot modify properties of the view - you can only respond to events in the view.

Maybe I'm totally off base in what a contoller should or shouldnt be able to do... but what I want is to decouple my view from my controller... and this question was what I came up with. Any advice would be cool.

Thanks

Skawful
The interface pattern I showed above should provide this. Just make sure you only reference the interface rather than the real view.
Matt Breckon
I do a similar thing for Model View Presenter patterns in WinForms except that we can also modify properties on most of the views.
Matt Breckon
remember that objects can implement more than one interface so you could put all the events in one interface and all the write-access stuff in another.
Matt Breckon
Yes - your interface would solve this - but only if i knew every event that would need to be implemented... This would work great for certain controls... like a button - but can you think of a way that it would work more generically? Maybe i'm asking for too much...
Skawful
It helps if you edit your question when providing additional information rather than putting it an answer.
Dan Blanchard
Dan - ya I guess I wasn't logged in when looking for that button.I think this question is a misunderstanding of MVC, Interfaces, and dependency injection. I'm looking more into these topics. If anyone has any good links on the topics - that'd be awesome. - Thx
Skawful