Aggregate multiple events into one interface - c#

What alternative can one use to avoid exposing both events and an interface.
I have a class that has a determined life cycle: created, modified, ...
clients mainly GUIs need to hook up into the life cycle of that class so the simplest way to do it is to expose events, at the same time I need to move some responsibilities -that happen during the life cycle- out of the class so I came up with this solution:
Interface ILifeCycle
{
void OnCreated(...);
void OnModified(...);
// ...
}
classA
{
private ILifeCycle lifeCycle;
/// ...
public event EventHandler Created(object sender, EventArgs args);
public event EventHandler Modified(object sender, EventArgs args);
/// ...
protected void OnCreated()
{
lifeCycle.OnCreated(...);
if(Created!=null)
Created(this,EventArgs.Empty);
}
protected void OnModified()
{
lifeCycle.OnModified(...);
if(Modified!=null)
Modified(this,EventArgs.Empty);
}
/// ...
}
Doing this I can inject a Logger that implements ILifeCycle, and so move the logging responsibility to its own class,
but it feels like it's going to be a lot of repetition.
What clean alternatives would you recommend to achieve this?

In general Interface and Events/Delegates are used for two very different kinds of approach. Lets describe them each first -
Interface: The main purpose of interface is that it enforces some functionality to all implementations of that interface. And whenever you implement it in a subclass, you override the implementation of the super class. For example -
interface IA
{
void test();
}
class A : IA
{
public void test(){
}
}
class B : A
{
public void test(){
//you can only go up by calling base.test(), but cannot move down, because you do not know whether there is an implementation down the tree or not. So you cannot call it.
}
}
class C : B
{
public void test(){
//you can only go up by calling base.test(), but cannot move down, because you do not know whether there is an implementation down the tree or not. So you cannot call it.
}
}
As you can see, with interface you can only look back but cannot look forward and assume there will be any more implementations.
Events: Events are created for a different purpose. lets just say you want to give the developers some facility to rely on some activities and do some other activities based on that activities and changes, and most importantly they will be implement this in future. The events will not depend on your implementation, they will just subscribe to it and do something based on that. Whether they exists or not, your own implementation does not change or the behavior of your own code does not changes based on them. In other words, you can only move down the tree. The base class captured the event and then propagates them down the tree.
These are the usual uses of Interface and Events and they are meant to be used that way. But its not completely impossible to code such that it will entirely depend on interface and vice versa, i.e. code entirely dependent on events but that is not the way they are meant to be.
In This Case: In your case, I am thinking you are trying to achieve a modular system that will not depend on each other but again subscribe to events. There are other architectures and patterns for this, specially IOC containers will be a very helpful for you, that will entirely be interface dependent, you will not need events. Some .net IOC containers are AutoFac, Castle.Windsor, MEF
I myself, like MEF the most, here is a post on MEF that I wrote few years back, shows you how you can inject run-time handlers inside a container -
http://mahmudulislam.me/2012/04/20/1a-managed-extensibility-framework-introduction/
BTW, article is a bit old, I am working on updating this one.
Solution with IOC: I am giving a probable solution with MEF -
Interface ILifeCycle
{
void OnCreated(...);
void OnModified(...);
...
}
[Export(typeof(ILifeCycle))] //export our classes for injection
classB : ILifeCycle{
public void OnCreated(...)
{
....
}
public void OnModified(...){
}
}
[Export(typeof(ILifeCycle))] //export our classes for injection
classC : ILifeCycle{
public void OnCreated(...)
{
....
}
public void OnModified(...){
}
}
classA
{
[ImportMany] //get all exported classes for injection
private IList<ILifeCycle> _observers;
protecetd void OnCreated()
{
//use MEF to build composition and then do the following
foreach(var o in _observers){
o.OnCreated(...);
}
}
protecetd void OnModified()
{
//use MEF to build composition and then do the following
foreach(var o in _observers){
o.OnModified(...);
}
}
...
}
This is a very basic solution. But in your case you might wanna make use of asynchronous programming. Because there is very big difference between Events and Interfaces. By default, events handlers are call in a separate thread and thus it does not halt the caller, but interface implement will hang the caller until the method finishes. So make sure you use asynchronous programming to not block your main process.
Asynchronous Programming with Async and Await (C# and Visual Basic)

I'm not sure I understood you well but I think you worry about repetitions in different types implementing ILifeCycle. So, you can take advantage of inheritance:
abstract class LifeCycleBase
{
public void OnCreated(...)
{
.....
}
public void OnModified(...);
{
.....
}
...
}
class LifeCycleLoger : LifeCycleBase
{
public void OnCreated(...)
{
....
base.OnCreate();
}
....
}

Related

Interface Listener C# without subscribing

I have been using a lot of APIs where to listen to some event I just need to implement an interface, but it doesn't require me to subscribe, how they do that?
To explain it better here is how I usually do my listeners
interface IListener
{
void OnEventHappen();
}
public class EventClass
{
public static Action onEvent;
}
public class ListenerClass : IListener
{
//constructor
public ListenerClass()
{
EventClass.onEvent += OnEventHappen;
}
//function from IListener interface
public void OnEventHappen() { //something... }
}
but in those APIs it is not necessary to subscribe anywhere, I just need to implement the interface like this: (I removed the EventClass because in those APIs I have no access to the classes who trigger the events)
interface IListener
{
void OnEventHappen();
}
public class ListenerClass : IListener
{
//function from IListener interface
public void OnEventHappen() { //something... }
}
In c# such behavior can be achieved using reflection.
One example in comments mentions Unity and it's methods like OnBeginDrag or Update. Those are not called using c# events. Unity is mostly written in c++ and after your c# code is compiled Unity looks for all classes implementing certain interfaces or inheriting from certain classes (like MonoBehaviour) and checks if they have matching methods (like Update()) so it can call them later when necessary.
Another comment mentions Photon, a networking engine commonly used with Unity. In this case there is no "magic" or even reflection. To receive Photon's callbacks you have to call PhotonNetwork.AddCallbackTarget method and pass instance of your class as an argument. Only confusing thing in case of Photon is fact, that you don't have to do that directly. Instead of calling this method yourself, you can just inherit from MonoBehaviourPunCallbacks class which implements all Photon's callback interfaces and calls PhotonNetwork.AddCallbackTarget in it's OnEnable method. That method is in turn called by Unity like I explained earlier.

Using a public method of derived class that is not in interface definition

New to OOP here. I have defined an interface with one method, and in my derived class I defined another public method. My client code is conditionally instantiating a class of the interface type, and of course the compiler doesn't know about the method in one of the derived classes as it is not part of the underlying interface definition. Here is what I am talking about:
public interface IFileLoader
{
public bool Load();
}
public class FileLoaderA : IFileLoader
{
public bool Load();
//implementation
public void SetStatus(FileLoadStatus status)
{
//implementation
}
}
public class FileLoaderB : IFileLoader
{
public bool Load();
//implementation
//note B does not have a SetStatus method
}
public enum FileLoadStatus
{
Started,
Done,
Error
}
// client code
IFileLoader loader;
if (Config.UseMethodA)
{
loader = new FileLoaderA();
}
else
{
loader = new FileLoaderB();
}
//does not know about this method
loader.SetStatus (FileStatus.Done);
I guess I have two questions:
What should I be doing to find out if the object created at run-time has the method I am trying to use? Or is my approach wrong?
I know people talk of IOC/DI all the time. Being new OOP, what is the advantage of using an IOC in order to say, "when my app asks
for an IFileLoader type, use concrete class x", as opposed to simply
using an App.Config file to get the setting?
Referring to your two questions and your other post I'd recommend the following:
What should I be doing to find out if the object created at run-time has the method I am trying to use? Or is my approach wrong?
You don't necessarily need to find out the concrete implementation at runtime in your client code. Following this approach you kinda foil the crucial purpose of an interface. Hence it's rather useful to just naïvely use the interface and let the concrete logic behind decide what's to do.
So in your case, if one implementation's just able to load a file - fine. If your other implementation is able to the same and a bit more, that's fine, too. But the client code (in your case your console application) shouldn't care about it and just use Load().
Maybe some code says more than thousand words:
public class ThirdPartyLoader : IFileLoader
{
public bool Load(string fileName)
{
// simply acts as a wrapper around your 3rd party tool
}
}
public class SmartLoader : IFileLoader
{
private readonly ICanSetStatus _statusSetter;
public SmartLoader(ICanSetStatus statusSetter)
{
_statusSetter = statusSetter;
}
public bool Load(string fileName)
{
_statusSetter.SetStatus(FileStatus.Started);
// do whatever's necessary to load the file ;)
_statusSetter.SetStatus(FileStatus.Done);
}
}
Note that the SmartLoader does a bit more. But as a matter of separation of concerns its purpose is the loading part. The setting of a status is another class' task:
public interface ICanSetStatus
{
void SetStatus(FileStatus fileStatus);
// maybe add a second parameter with information about the file, so that an
// implementation of this interface knows everything that's needed
}
public class StatusSetter : ICanSetStatus
{
public void SetStatus(FileStatus fileStatus)
{
// do whatever's necessary...
}
}
Finally your client code could look something like the follwing:
static void Main(string[] args)
{
bool useThirdPartyLoader = GetInfoFromConfig();
IFileLoader loader = FileLoaderFactory.Create(useThirdPartyLoader);
var files = GetFilesFromSomewhere();
ProcessFiles(loader, files);
}
public static class FileLoaderFactory
{
public static IFileLoader Create(bool useThirdPartyLoader)
{
if (useThirdPartyLoader)
{
return new ThirdPartyLoader();
}
return new SmartLoader(new StatusSetter());
}
}
Note that this is just one possible way to do what you're looking for without having the necessity to determine IFileLoader's concrete implementation at runtime. There maybe other more elegant ways, which furthermore leads me to your next question.
I know people talk of IOC/DI all the time. Being new OOP, what is the advantage of using an IOC [...], as opposed to simply using an App.Config file to get the setting?
First of all separating of classes' responsibility is always a good idea especially if you want to painlessly unittest your classes. Interfaces are your friends in these moments as you can easily substitute or "mock" instances by e.g. utilizing NSubstitute. Moreover, small classes are generally more easily maintainable.
The attempt above already relies on some sort of inversion of control. The main-method knows barely anything about how to instantiate a Loader (although the factory could do the config lookup as well. Then main wouldn't know anything, it would just use the instance).
Broadly speaking: Instead of writing the boilerplate factory instantiation code, you could use a DI-Framework like Ninject or maybe Castle Windsor which enables you to put the binding logic into configuration files which might best fit your needs.
To make a long story short: You could simply use a boolean appSetting in your app.config that tells your code which implementation to use. But you could use a DI-Framework instead and make use of its features to easily instantiate other classes as well. It may be a bit oversized for this case, but it's definitely worth a look!
Use something like:
if((loader as FileLoaderA) != null)
{
((FileLoaderA)loader).SetStatus(FileStatus.Done);
}
else
{
// Do something with it as FileLoaderB type
}
IoC is normally used in situations where your class depends on another class that needs to be setup first, the IoC container can instantiate/setup an instance of that class for your class to use and inject it into your class usually via the constructor. It then hands you an instance of your class that is setup and ready to go.
EDIT:
I was just trying to keep the code concise and easy to follow. I agree that this is not the most efficient form for this code (it actually performs the cast twice).
For the purpose of determining if a particular cast is valid Microsoft suggests using the following form:
var loaderA = loader as FileLoaderA;
if(loaderA != null)
{
loaderA.SetStatus(FileStatus.Done);
// Do any remaining FileLoaderA stuff
return;
}
var loaderB = loader as FileLoaderB
if(loaderB != null)
{
// Do FileLoaderB stuff
return;
}
I do not agree with using is in the if. The is keyword was designed to determine if an object was instantiated from a class that implements a particular interface, rather than if a cast is viable. I have found it does not always return the expected result (especially if a class implements multiple interfaces through direct implementation or inheritance of a base class).

Resolve forward references in modular architecture

In my (C#) software project, I have a several modules (represented by separate Visual Studio projects) that - due to historical reasons - have lots of circular dependencies (tight coupling).
I'm currently trying to resolve/remove the circular references. I've already added dependency injection - but this, of course, doesn't resolve/remove the circular references.
So, I was thinking about using events to resolve the "forward" dependencies. Instead of calling forward dependencies directly, they would register then on this event.
However, some of these dependencies need to be executed before others, like this (dumbed down) example:
void DeleteCompany(int companyId)
{
// must run before other dependencies
ForwardDepend1.OnCompanyDeleted(companyId);
// can run in parallel
ForwardDepend2.OnCompanyDeleted(companyId);
ForwardDepend3.OnCompanyDeleted(companyId);
// must run as last command
this.OnCompanyDeleted(companyId);
}
All classes of ForwardDependX depend on the current class; so these are the circular references I want to resolve.
Are there any existing patterns that solve this kind of "complex event" mechanism? Or are there maybe other, better ways to solve this problem?
I've tried googling this problem but I couldn't find any good keywords for the search.
I think using events to improve a tightly coupled design is not the best choice, because they tend to make dependencies less obvious. And you really need to have all dependencies explicit to tackle the circular references.
I suggest you rather apply the dependency inversion principle and the interface segregation principle in a step by step manner. Pass newly introduced interfaces in to their clients through the constructor and use DI to compose them.
Also, a dependency visualizer really helps in these situations. I've used Resharper and NDepend for these tasks in the past, both work well.
Example of the DIP
Here is an example that shows how you can resolve a circular dependency with the DIP. So assume you have two classes that depend on each other:
class A
{
private readonly B _b;
public A(B b) {
_b = b;
}
public void DoIt() {
// ...
}
}
class B
{
public void DoSomething(A a) {
a.DoIt();
}
}
This means we have a dependency graph like this:
A <--> B
Now introduce an interface on the class that constitutes the weaker dependency, in this case A (because A is only used temporarily in B).
interface IA
{
void DoIt();
}
class A : IA
{
private readonly B _b;
public A(B b) {
_b = b;
}
public void DoIt() {
// ...
}
}
class B
{
public void DoSomething(IA a) {
a.DoIt();
}
}
With the introduction of the interface, the dependency circle has been broken:
A ----
| |
v v
IA <-- B
That wont solve your problem. Instead you should create multiple events and hook them up.
You say that you have dependencies 1-3 that must run on order on the CompanyDeleted event and that your own event handler should run last.
That is a fragile approach. Let's assume that the dependencies instead are named like this:
MessageManager
ProjectManager
UserManager
The motivation is that the message manager must run first so that it can find all users from the user manager and all projects from project manager to be able to delete it's messages.
You can instead reverse that process. Listen on the event UserDeleted to delete all messages for a user and on the ProjectDeleted even to delete all messages for the project.
So now you have no temporal coupling between the event handlers of the CompanyManager as you only have one event handler for it.
It will of course mean more work as you have to identify new events and create them. The good thing is that you can solve the event subscription with the help of your IoC container.
Create a new interface called IEventHandler<T>:
public interface IEventHandler<T>
{
void Handle(T evt);
}
and let your classes implement it:
public class UserManager : IEventHandler<CustomerDeleted>
{
public UserManager(IUserRepository repos, IEventPublisher publisher)
{
}
public void Handle(CustomerDeleted evt)
{
var users = _repos.FindUsersForCustomer(evt.CustomerId);
foreach (var user in users)
{
_repos.Delete(user);
_publisher.Publish(new UserDeleted(user.Id, user.CustomerId));
}
}
}
The event publisher itself uses your container (for service location). The implementation varies from container to container:
public class EventPublisher : IEventPublisher
{
public EventPublisher(IYourContainerInterface container)
{
}
public void Publish<TEvent>(TEvent evt)
{
var handlers = _container.ResolveAll<TEvent>();
foreach (var handler in handlers)
{
handler.Publish(evt);
}
}
}
Hope that helps.

Program to an interface not an implementation confusion

I'm trying to get into the habit of coding to an interface rather than an implementation and whilst in most cases I can see the reasoning there are a few where I struggle.
Take this really simple example:
public interface IAuditLog
{
void AddLog(string log);
}
public class AuditLog : IAuditLog
{
public void AddLog(string log)
{
//implementation
}
}
To call the audit log class:
public partial class AuditLogPage : System.Web.UI.Page
{
protected void btnAddLog_Click(object sender, EventArgs e)
{
IAuditLog objAuditLog = new AuditLog();
objAuditLog.AddLog("test log");
}
}
I still have to use AuditLog when instantiating, so what's the point? If the AddLog method signature changes i'm still going to have to go through all my pages that use it and amend the code. Am I missing the point?
Thanks for any help in advance,
Wilky.
In the example if you switched out FileAuditLogger() with DatabaseAuditLogger() or EventLogAuditLogger() you can switch implementations without having to rewrite your code.
Typically you'd use an IoC container (Autofac, StructureMap, Unity, etc.) to automatically wire up the object instantiation. So instead of calling new AuditLog() you would call IoC.Container.Resolve<IAuditLog>()
Let me know if you'd like more information.
Let imagine that there there are two AuditLog classes
class AuditLogToDatabase : IAuditLog // writes to database
and another is
class AuditLogToFile : IAuditLog // writes to file
like
protected void btnAddLog_Click(object sender, EventArgs e)
{
IAuditLog objAuditLog = AuditLogFactory.GetAuditLog();
objAuditLog.AddLog("test log");
}
now you can inject any class based on some configuration at run time without changing the actual implementation
This doesn't necessarily mean that you have to actually use a C# interface. An interface in OOP terms is the publicly visible façade of an API. It's a contract and externally visible results of operations should be specified. How exactly it works beneath the surface should be irrelevant so that you can swap out the implementation at any time.
Of course, in that regard an interface is a method of being able to use different implementations, but so is an abstract base class or even a non-abstract class others can derive from.
But more to the exact point of your question: Of course, when instantiating a class its type must be known, but you don't necessarily have to create the class instance there. You could set an IAuditLog from the outside or get it via a factory class, etc. where you wouldn't know, at that exact point in the code, what exact type you're getting (except that it's compatible with IAuditLog).
This is actually useful when you create the AuditLog instance from a method say like a Factory method and you have more than one AuditLogXXX classes derived from the IAuditLog interface.
So, instead of using this code:
IAuditLog objAuditLog = new AuditLog();
You would actually use this code when you program to an interface:
IAuditLog objAuditLog = LogFactory.GetAuditLog(); //This call is programmed to an interface
where GetAuditLog() is an interface typed method defined on the LogFactory class as below:
class LogFactory
{
public IAuditLog GetAuditLog() // This method is programmed to an interface
{
//Some logic to make a choice to return appropriate AuditLogXXX instance from the factory
}
}

OOD, inheritance, and Layer Supertype

I have a question concerning holding common code in a base class and having the derived class call it, even though the derived class's trigger method has been dispatched from the base. So, base->derived->base type call stack.
Is the following look OK, or does it smell? I have numbered the flow steps...
public abstract class LayerSuperType
{
public void DoSomething() // 1) Initial call from client
{
ImplementThis(); // 2) Polymorphic dispatch
}
protected abstract void ImplementThis();
protected void SomeCommonMethodToSaveOnDuplication(string key) // 4)
{
Configuration config = GetConfiguration(key);
}
}
public class DerivedOne : LayerSuperType
{
protected virtual void ImplementThis() // 2)
{
SomeCommonMethodToSaveOnDuplication("whatever"); // 3) Call method in base
}
}
public class DerivedTwo : LayerSuperType
{
protected virtual void ImplementThis() // 2)
{
SomeCommonMethodToSaveOnDuplication("something else"); // 3) Call method in base
}
}
That looks absolutely fine. Perfect example of why you'd use an abstract class over an interface. It's a bit like a strategy pattern and I have used this fairly regularly and successfully.
Make sure that what the class doing is still dealing with one 'concern' though, only doing one task. If your base class does repository access but the objects are representing documents, don't put the functionality in the base class, use a separate repository pattern/object.
Looks like a very simplified Template Method Pattern where your sub-classes do some specific kinds of things at the right points in the implementation of your algorithm, but the overall flow is directed by a method on the base class. You've also provided some services to your sub-classes in the form of base class methods; that's ok too as long as you're good as far as SOLID goes.
Why not public abstract void DoSomething() and forget about ImplementThis() altogether?
The only reason I can see to leave ImplementThis() is if you want to maintain a consistent interface with DoSomething() which later on down the road will allow the signature of ImplementThis() to change without a breaking change to callers.
I agree that you should maintain a single concern with the class's responsibility but from an overall OOP perspective this looks fine to me. I've done similar on many occasions.
It does smell a little that SomeCommonMethodToSaveOnDuplication is being called in two different ways. It seems to be doing two unrelated things. Why not have two methods?

Categories