C# How to expose events in DLL - c#

I have a DLL that needs to expose "event subscription" so a App that uses my DLL can subscribe to a specific event to get data. (The DLL itself subscribes to an event from a SDK)
I am pretty new to events, so please be gentle with me and explain.
I have a DLL that looks for example like this:
internal class BaseClass
{
}
internal Class DerivedClass : BaseClass, InterfaceClass
{
public event TrackingEventHandler NewTrackingEventObservations;
public delegate void TrackingEventHandler(Object sender, TrackingEventArgs e);
}
In my interface, I want to expose the delegate TrackingEventHandler.
Interface:
public interface InterfaceClass
{
event TrackingEventHandler NewTrackingEventObservations; // <- Error: TrackingEventHandler is less accessable then the field NewTrackingEventObservations
}
How can I fix this issue?
Thanks a lot!

The error you’re getting is because TrackingEventHandler is contained in a class that is internal (only accessible by files within the same assembly, see this link), but the interface you’re trying to expose is public. You can either make the containing class public, or define TrackingEventHandler outside of this class (it doesn’t need to be contained in a class definition).
Here’s an example of defining it outside of a class:
namespace someNamespace
{
public delegate void TrackingEventHandler(Object sender, TrackingEventArgs e);
internal Class BaseClass{ }
internal Class DerivedClass : BaseClass, InterfaceClass
{
public event TrackingEventHandler NewTrackingEventObservations;
}
}

Related

Event setting with delegate

Hello i create a class which contains the event and the variables :
namespace FS
{
public class SomeEventArgs : EventArgs
{
public readonly string SomeVarible;
public SomeEventArgs (string someVarible)
{
SomeVarible= someVarible;
}
}
}
and i want to use this in another class :
namespace FS
{
delegate void Example(object sender, SomeEventArgs e);
public class OtherClass
{
public event Example example;
}
and i get this error :
Error CS7025 Inconsistent accessibility: event type 'Example' is less
accessible than event 'OtherClass.example'
You haven't specified access modifier of your delegate void Example(object sender, SomeEventArgs e); default one is internal, but event in class OtherClass is public.
It's illogical to expose something to other libraries with public modifier, while the underlying type is only accessible inside your library, because it is internal.
Easiest solution is making your delegate public, or your event public internal, depends how you want to use it.
You can find more about access modifiers here in documentation.

initialized delegates in class diagram

I use Visual Studio 2015, and I have created a class diagram to have an overview of my most-used classes and their members.
I have a delegate defined in a class named UserMessage:
public delegate void ProcessUserMessage(UserMessage message);
I use this delegate in an other class:
public UserMessage.ProcessUserMessage ProcessUserMessage;
So far no problems.
Because I hate testing the callback for null every time, I hook up a no-op event handler at initialization, as suggested here:
public UserMessage.ProcessUserMessage ProcessUserMessage = delegate { };
But when I do that, and re-open the class diagram, it fails to load, saying:
Code could not be found for one or more shapes in class diagram 'ClassDiagram1.cd'. Do you want to attempt to automatically repair the class diagram?
The auto-repair doesn't work of course ;-(
Even when I place this initiatlization in the class' constructor, instead of at the declaration, the same error appears.
I fail to understand what's wrong. Any clues?
Update:
I created a blank project with just the failing code:
public partial class MainWindow
{
public UserMessage.ProcessUserMessageDelegate ProcessUserMessage = delegate { };
}
public class UserMessage
{
public delegate void ProcessUserMessageDelegate(string foo);
}
The strange thing is that the class diagram for MainWindow loads fine, but for UserMessage it fails. But I am not changing anythign for UserMessage.
It loads OK if I change class MainWindow to:
public partial class MainWindow
{
public UserMessage.ProcessUserMessageDelegate ProcessUserMessage;
}
Found the solution...
The anonymous no-op delegate must conform to the delegate definition, so all I had to add was add the argument ((string foo) in this example):
public partial class MainWindow
{
public UserMessage.ProcessUserMessageDelegate ProcessUserMessage = delegate (string foo){ };
}
public class UserMessage
{
public delegate void ProcessUserMessageDelegate(string foo);
}

Share a private implementation between two classes in C#

I'm looking for a way to share the implementation of two classes without exposing any details of that sharing. I was hoping to create this basic class structure:
public interface MyInterface
class MyCommonImpl : MyInterface
public class MyImplA : MyCommonImpl
public class MyImplB : MyCommonImpl
MyCommonImpl implements the functions of MyInterface and has one abstract function provided in MyImplA and MyImplB. A user of MyImplA should not know about MyCommonImpl in any fashion, it's just an implentation detail.
I've considered doing manual composition, but this involves copying a lot of code to forward the functions. It's also problematic since there are events implemented in MyCommonImpl, and one of their parameters is a sender. This requires putting a proxy handler and partially rewriting events. Basically composition would require more code than simply copy-pasting the entire MyCommonImpl.
How can I do this without having to duplicate a lot of code?
You can move the interfaces and implementations to another assembly and mark them internal which will hide the abstract function of MyCommonImpl. Taking it further, you could explicitly implement the interfaces inside that assembly to completely hide their methods from callers leaving only those methods declared public on MyImplA visible.
The internal casts for the explicit implementation are a bit nasty though...
In a separate assembly:
namespace Private
{
internal interface IMyInterface
{
void InterfaceMethod();
}
public abstract class MyCommonImpl : IMyInterface
{
internal MyCommonImpl()
{
// internal ctor to stop callers constructing
}
void IMyInterface.InterfaceMethod()
{
Console.WriteLine("InterfaceMethod");
}
internal abstract void CommonAbstract();
}
public class MyImplA : MyCommonImpl
{
internal override void CommonAbstract()
{
((IMyInterface)this).InterfaceMethod();
Console.WriteLine("CommonAbstract");
}
public void ImplAMethod()
{
CommonAbstract();
Console.WriteLine("ImplAMethod");
}
}
}

Object oriented design issues - abstract, derived/implementing types - a use case scenario

I have no practical experience with OO design, thus I am hesitant as to the solution I adopted for the following problem:
I have to process network text files that come from N different sources, in different formats - with the processing consisting in the classical reading, computations, and insertion into database.
The solution I devised was to create a class that defines all functionalities/behaviors that are core/file-format-independent, and create derived classes from the latter where each contain the appropriate format-reading logic, according to the file-type the given class handles.
All files are read via File.ReadAllLines(), what differs is mapping fields from the file into the main object's variables. So I did this by defining an event in the base class, that is called after File.ReadAllLines(), and all derived classes attach their mapping logic to the inherited event.
But I understand this solution is not correct design-wise. First of all, there is no meaning in instantiating the base class, so it should be abstract. The reason I did not make it abstract is that the construction code for all the derived objects is the same, so I defined it as the base constructor. Should I declare an "Initialize" method in the abstract class and simply call it in every derived class's constructor? (looks weird...)
Perhaps interfaces? I don't see how using an interface would give me any benefits here, besides it will not solve this "constructor" problem...
What is the correct solution?
Code demonstration of my scenario:
public delegate void myDelegate(object parameter);
class Base
{
#region Attributes
...
#endregion
public Base(object p)
{
//initialization code
...
}
#region Methods
protected void m1() { }
protected void m2() { }
...
#endregion
public event myDelegate myEvent;
}
class Child1
{
public Child1(object o) : base(o)
{
this.myEvent += new myDelegate(ChildMethod);
}
public void ChildMethod(object o)
{
...
}
}
First of all, there is no meaning in instantiating the base class, so it should be abstract. The reason I did not make it abstract is that the construction code for all the derived objects is the same, so I defined it as the base constructor.
You still can make the base class abstract yet have common constructor logic in the base class constructor. I see in your code you've already figured out how to call the base class constructor; that's all you need to do.
abstract class Base {
public Base(object o) { }
public abstract void M();
}
class Derived : Base {
public Derived(object o) : base(o) { }
public override void M() { }
}

C#: Is there way to ensure an object is only accessible through its events?

Is there a way to create some sort of interface that only allows the object to be accessible through events?
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;
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).
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.
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.

Categories

Resources