Giter Club home page Giter Club logo

ced's Introduction

CED

Configurable Event Dispatcher for .NET

This library is written in .NET Standard 2.0 and should work with .NET Framework 4.6.1 and higher as well as .NET Core 2 and higher. The test project is targeted at .NET Framework 4.6.1 as a proof of baseline compatability.

Objective

The goal of this library is to allow config-based setting hooks between .NET Events and Handlers. Traditionally one would hardcode the handlers to specific events:

public event EventHandler<string> SomethingHappened;

...

someObject.SomethingHappened += HandlerMethod;

this however creates relatively tight coupling between the classes, at least in consumer -> producer direction. Additionally any changes to what listens to what event required recompilation.

EDC provides an ability to add a config section to your solution that will define how various classes should subscribe to events. This allows for no-recompilation-needed changes, (in the future even runtime changes), as well as using single compiled application with different sets of configuration.

Basic Usage

  1. Register EDC config section (CED.Config.EventConfigSection):
  <configSections>
    <section name="eventConfig" type="CED.Config.EventConfigSection, CED"/>
  </configSections>
  1. Add config section
<eventConfig throwOnErrors="false">
  <events>
  
    <event>
      <producer qualifiedClassName="CED.Tests._461.Producer, CED.Tests.461" eventName="NoDataEvent" />
      <consumers>
        <consumer qualifiedClassName="CED.Tests._461.Consumer, CED.Tests.461" methodName="TriggerNoData" />
      </consumers>
    </event>
    
  </events>
</eventConfig>

Please note, that while <event> expects a single <producer />, it can contain any number of <consumer /> entries under <consumers /> container.

  1. Create EventDispatcher. You have a choice of using any of the three constructors:
public EventDispatcher(Func<Type, object> resolver = null) // use default "eventConfig" section name, loaded from currenct config
public EventDispatcher(string configSectionName, Func<Type, object> resolver = null) // use whatever section name you have chosen in current config
public EventDispatcher(EventConfigSection eventConfigSection, Func<Type,object> resolver = null) // load the section yourself and pass it to the constructor

The resolver is optional, but usually needed, if the event producers and consumers are not static. See "Resolution" section below.

  1. Call HookAll() method. This will apply all loaded consumers to their respective consumers.

That's it - all hooks should be applied, and when events are triggered, defined consumer methods should be called.

Configuration

eventConfig

<eventConfig throwOnErrors="true"> Contains single <events /> container.

  • throwOnErrors (default true). If this is set to false, the library should not throw exceptions. This means that setting up the hooks might fail partially or completely.

events

Contains <event> entries. A single event should have it's own entry. No configurable options available.

event

Contains a single <producer /> and single <consumers /> elements. No configurable options available.

producer

<producer qualifiedClassName="Namespace.Class, Assembly" eventName="EventName" findInstance="true" />

  • qualifiedClassName - a fully qualified name of the class or interface that contains the event
  • eventName - name of the event
  • findInstance (default: true) - whether to use the resolver to find an instance, or treat this as a static event

consumers

Contains zero or more <consumer /> entries. No configurable options available

consumer

<consumer qualifiedClassName="Namespace.Class, Assembly" methodName="MethodName" findInstance="true" />

  • qualifiedClassName - a fully qualified name of the class or interface that contains the handler method
  • methodName - name of the method that should be used as event handler
  • findInstance (default: true) - whether to use the resolver to find an instance, or treat this as a static event

Resolution

Unless the event or handler are static, the library needs a way to resolve a fully qualified type name to an instance. On small scale this can be used simply by creating a method manually:

public object Resolver(Type type){
  if(type == typeof(MyType1)
    return instanceOfMyType1;
    ...
}

though in most scenarios the method will be wrapping a Dependency Resolver from one of the containers like Autofac:

var resolver = new Func<Type, object>(type => DependencyResolver.Current.GetService(type));

Planned development

  1. Remove dependency on NLog
  2. Provide better feedback to the user about possible failures and results of calling Hook() and Unhook()
  3. Test and fix if necessary loading the resolver from config (undocumented child element of <eventConfig /> called <locator qualifiedClassName="Namespace.Class, Assembly" methodName="MethodName" />, this needs to be static. This removes the necessity to pass resolver manually from code.
  4. Improve unit test coverage, specifically for negative scenarios.

ced's People

Contributors

p-kaczynski avatar

Stargazers

Emilian BALANESCU avatar

Watchers

James Cloos avatar  avatar

ced's Issues

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.