di-hook

dI.Hook – Creating a dependency injection container

September 9, 2012 Applications, CSharp, Open Source, Visual Studio , , , ,

If you are new to dI.Hook, please visit the di.Hook Product Page for Overview, Release Version and Source Code.

Some posts you might want to read would be:

  1. How to create a HookRepository?
  2. How to add hooks to HookRepository?
  3. How to add hooks via configuration file to a HookRepository?
  4. How to invoke all hooks using dI.Hook?
  5. How to invoke hooks that satisfy a condition?
  6. How to retrieve an object of hook?
  7. How to remove hooks from HookRepository?
  8. How to ignore hook on specific method?

So this is the ninth article in the series which will deal with creating a dependency injection container and using them in your applications

Creating a dependency container is very simple.  You can either choose a default implementation of Container, or you can implement the interface IContainer and write your own definition of container.    The implementation you would require to implement would be

  1. public interface IContainer
  2. {
  3.     ReadOnlyCollection<dIHook.Objects.ContainerItem> Collection { get; }
  4.     ReadOnlyCollection<Guid> Keys { get; }
  5.     void Register<TClass>() where TClass : class;
  6.     void Register<TClass>(Guid key) where TClass : class;
  7.     void Register<TInterface, TImplementation>() where TImplementation : class, TInterface;
  8.     void Register<TInterface, TImplementation>(Guid guid) where TImplementation : class, TInterface;
  9.     void Register<TInterface>(Guid key, TInterface objectValue);
  10.     void Register<TInterface>(TInterface objectValue);
  11.     TInterface Resolve<TInterface>() where TInterface : class;
  12.     TInterface Resolve<TInterface>(Guid key) where TInterface : class;
  13.     ReadOnlyCollection<Type> Types { get; }
  14. }

 

Assuming that you are not implementing this interface and are using the default implementation provided with dI.Hook, you would involve having

  1. Some business interfaces and entities
  2. Container having a definition of interface and implemented entities
  3. Container resolving these entity objects

For the sake of understanding, let’s have a eCommerce case study where we have 3 interfaces –

  • ICustomer – Represents customer and his order
  • INotifier – Notification service for the customer
  • IBillingProcessor – Processor that takes the payment type and processes the billing

So let’s quickly set the stage with these interface and their implementation

  1. public interface IBillingProcessor
  2. {
  3.     void ProcessPayment(OnlineOrder order);
  4. }
  5. public class BillingProcessor : IBillingProcessor
  6. {
  7.     private PaymentType _paymentType;
  8.     public BillingProcessor(PaymentType paymentType) {}
  9.     public void ProcessPayment(OnlineOrder order) { }
  10. }
  11. public enum PaymentType { Cash,CreditCard}
  12. public interface ICustomer
  13. {
  14.     void UpdateCustomerOrder(int customerId, string product);
  15. }
  16. public class InternetCustomer : ICustomer
  17. {
  18.     public InternetCustomer() { }
  19.     public void UpdateCustomerOrder(int customerId, string product) { }
  20. }
  21. public interface INotifier
  22. {
  23.     void SendReceipt(OnlineOrder order);
  24. }
  25. public class EmailNotifer : INotifier
  26. {
  27.     public EmailNotifer() { }
  28.     public void SendReceipt(OnlineOrder order) { }
  29. }

       

      Now, let’s use the container with these business entities

      1. Container container = new Container();
      2. container.Register<IBillingProcessor, BillingProcessor>();
      3. container.Register<ICustomer, InternetCustomer>();
      4. container.Register<INotifier, EmailNotifer>();

       

      The above code creates a default objects of the BillingProcessor, InternetCustomer and EmailNotifier.  If you want to pass your own object you could write as below (see BillingProcessor object)

      1. Container container = new Container();
      2. BillingProcessor billingProcessor = new BillingProcessor(PaymentType.CreditCard);
      3. container.Register<IBillingProcessor>(billingProcessor);
      4. container.Register<ICustomer, InternetCustomer>();
      5. container.Register<INotifier, EmailNotifer>();

       

      Now let’s place an order on an eCommerce website using this container.  An eCommerce class would be of no use without a reference to ICustomer, IBillingProcessor and INotifier.  So eCommerce class for this example would be

      1. public class ECommerce
      2. {
      3.     public void Process(OnlineOrder order)
      4.     {
      5.         _BillingProcessor.ProcessPayment(order);
      6.         _Customer.UpdateCustomerOrder(order.CustomerId,
      7.             order.Product);
      8.         _Notifier.SendReceipt(order);
      9.  
      10.         Debug.WriteLine("Process called");
      11.     }
      12.  
      13.     public ECommerce(IBillingProcessor billingProcessor,
      14.                 ICustomer customer,
      15.                 INotifier notifier)
      16.     {
      17.         _BillingProcessor = billingProcessor;
      18.         _Customer = customer;
      19.         _Notifier = notifier;
      20.  
      21.     }
      22.  
      23.     IBillingProcessor _BillingProcessor;
      24.     ICustomer _Customer;
      25.     INotifier _Notifier;
      26. }

       

      So your eCommerce takes objects of ICustomer, IBillingProcessor and INotifier in the constructor and in the Process method, it

      1. Calls BillingProcessor to ProcessPayment for the order
      2. Calls Customer to UpdateCustomerOrder
      3. Calls Notifier to send notification

      Now let’s see how this can be invoked using dI.Hook container that we created

      1. OnlineOrder onlineOrder = new OnlineOrder()
      2. {
      3.     CustomerId = 12212,
      4.     EmailAddress = "[email protected]",
      5.     Price = 400,
      6.     Product = "NewProduct"
      7. };
      8. ECommerce commerce = container.Resolve<ECommerce>();
      9. commerce.Process(onlineOrder);

      The above code creates an object of ECommerce class.  Now what is important here is to see what internally happens.  When you call Resolve method, it tries creating an object of ECommerce class.  It finds that its constructor requires objects of IBillingProcessor, ICustomer and INotifier.  Now since you have already registered objects of these interfaces the dI.Hook Container retrieves the object from the collection and then will try to create an object of ECommerce.  If, however, ECommerce constructor required an un-registered object it will try to create a default object and add it in the container.

      So if you explicitly created an object of BillingProcessor with payment type as CreditCard and added them in Container, it will use that object; otherwise, it will use default object of BillingProcessor with payment type as Cash

      dI.Hook Container ensures that it resolves the hierarchical dependencies automatically.  However if it is unable to resolve for any reason, it will throw an exception.

      dI.Hook – How to ignore hook on specific method?

      August 9, 2012 CSharp, Open Source, Visual Studio , , ,

       

      If you are new to dI.Hook, please visit the di.Hook Product Page for Overview, Release Version and Source Code.

      Some posts you might want to read would be:

      1. How to create a HookRepository?
      2. How to add hooks to HookRepository?
      3. How to add hooks via configuration file to a HookRepository?
      4. How to invoke all hooks using dI.Hook?
      5. How to invoke hooks that satisfy a condition?
      6. How to retrieve an object of hook?
      7. How to remove hooks from HookRepository?

      So this is the eighth article in the series which will deal with

      – Ignoring one or more hook objects when executing OnInvoke in a method
      – but NOT removing the hook from the repository

      Step 1 – Creating a repository and add hooks into a repository

      The first decision in creating a hook repository is to think whether you want to have lazy loading or not. Once you have decided you can go through the steps – Creating a Hook Repository using dI.Hook

      Be selective in adding hooks into a repository if you plan to invoke all of them at one go. If you are thinking of manually adding hooks to a repository, would suggest going through – Adding hooks manually into a repository. However, if you are planning to load them through configuration you can read – Loading a configuration set of hooks into repository

      How to ignore a hook being invoked on a method?

       

      The repository created in step 1 consists of 2 hooks.

      Method One – Ignoring all hooks

       

      Ignoring all hooks
      [TestMethod] [RemoveAllHooks] public void Test_Standard_RemoveHooks()
      {
          int invokedHooks = hookRepository.InvokeAll();
          Assert.AreEqual(0, invokedHooks);
      }

       

      Method Two – Ignoring hooks with particular name

      Ignore hooks with name LogHook
      [TestMethod] [RemoveHook(new[] { "LogHook" })] public void Test_Standard_RemoveHooksWithName()
      {
          int invokedHooks = hookRepository.InvokeAll();
          Assert.AreEqual(1, invokedHooks);
      }

      or, you can have multiple hook names in the list

      Ignore multiple hooks
      [TestMethod] [RemoveHook(new[] { "LogHook", "DiagnosticsHook" })] public void Test_Standard_RemoveHooksWithName_MultipleHooks()
      {
          int invokedHooks = hookRepository.InvokeAll();
          Assert.AreEqual(0, invokedHooks);
      }

      or, using multiple attributes for doing the same

      Ignoring multiple hooks
      [TestMethod] [RemoveHook("LogHook")] [RemoveHook("DiagnosticsHook")] public void Test_Standard_RemoveHooksWithName_MultipleAttributesInMethod()
      {
          int invokedHooks = hookRepository.InvokeAll();
          Assert.AreEqual(0, invokedHooks);
      }

       

      Method Three – Ignore a hook of specific type

       

      Ignoring a hook type
      [TestMethod] [RemoveHookType(typeof(LogHook))] public void Test_Standard_RemoveHooksWithType()
      {
          int invokedHooks = hookRepository.InvokeAll();
          Assert.AreEqual(hookRepository.Hooks.Length – 1, invokedHooks);
      }

      or

      Ignoring multiple hook types
      [TestMethod] [RemoveHookType(typeof(LogHook))] [RemoveHookType(typeof(DiagnosticsHook))] [RemoveHookType(typeof(LogHook))] public void Test_Standard_AddRemoveHookCombination()
      {
          int invokedHooks = hookRepository.InvokeAll();
          Assert.AreEqual(0, invokedHooks);
      }

       

      So using these techniques, you can have a method ignore one or many hooks.  These hooks will still remain in the repository and methods without these attributes will continue to invoke their OnInvoke method.

      dI.Hook – How to remove hooks from HookRepository?

      August 7, 2012 CSharp, Open Source, Visual Studio , , ,

      If you are new to dI.Hook, please visit the di.Hook Product Page for Overview, Release Version and Source Code.

      Some posts you might want to read would be:

      1. How to create a HookRepository?
      2. How to add hooks to HookRepository?
      3. How to add hooks via configuration file to a HookRepository?
      4. How to invoke all hooks using dI.Hook?
      5. How to invoke hooks that satisfy a condition?
      6. How to retrieve an object of hook?

      So this is the seventh article in the series which will deal with removing one or more hook objects from the repository.

      Step 1 – Creating a repository and add hooks into a repository

      The first decision in creating a hook repository is to think whether you want to have lazy loading or not. Once you have decided you can go through the steps – Creating a Hook Repository using dI.Hook

      Be selective in adding hooks into a repository if you plan to invoke all of them at one go. If you are thinking of manually adding hooks to a repository, would suggest going through – Adding hooks manually into a repository. However, if you are planning to load them through configuration you can read – Loading a configuration set of hooks into repository

      Step 2- How to remove an instance of a hook from a repository?

      When we are referring to adding an instance of a hook in a repository, there are multiple ways of doing it

      Method 1 – Removing hook instance( s ) at a time

      Removing a single hook
      [TestMethod] public void Test_Standard_RemoveHookObject()
      {
          hookRepository.Remove(new LogHook());
          Assert.AreEqual(1, hookRepository.Hooks.Length);
      }

      Method 2 – Removing a List of hooks

      Removing list of hooks
      [TestMethod] public void Test_Standard_RemoveHookList()
      {
          hookRepository.Remove(new List<IHook> { new LogHook(), new DiagnosticsHook() });
          Assert.AreEqual(0, hookRepository.Hooks.Length);
      }

      Method 3 – Removing hooks of a particular type

      Removing hook of a type
      [TestMethod] public void Test_Standard_RemoveHookType()
      {
          hookRepository.Remove(typeof(LogHook));
          hookRepository.Remove(typeof(DiagnosticsHook));
          Assert.AreEqual(0, hookRepository.Hooks.Length);
      }

      Method 4 – Removing all hooks

      Removing all hooks
      [TestMethod] public void Test_Lazy_RemoveAll()
      {
          hookRepository.RemoveAll();
          Assert.AreEqual(0, hookRepository.Hooks.Length);
      }

       

      So there are 4 ways to remove a hook from the repository so that any method using OnInvoke method on the repository will find the removed hook in the repository

      dI.Hook – How to retrieve an object of hook?

      August 6, 2012 CSharp, Open Source, Visual Studio , , ,

      If you are new to dI.Hook, please visit the di.Hook Product Page for Overview, Release Version and Source Code.

      Some posts you might want to read would be:

      1. How to create a HookRepository?
      2. How to add hooks to HookRepository?
      3. How to add hooks via configuration file to a HookRepository?
      4. How to invoke all hooks using dI.Hook?
      5. How to invoke hooks that satisfy a condition?

      So this is the sixth article in the series which will deal with retrieving one or more hook objects instead of just invoking them.

      Step 1 – Creating a repository and add hooks into a repository

      The first decision in creating a hook repository is to think whether you want to have lazy loading or not.  Once you have decided you can go through the steps – Creating a Hook Repository using dI.Hook

      Be selective in adding hooks into a repository if you plan to invoke all of them at one go.  If you are thinking of manually adding hooks to a repository, would suggest going through – Adding hooks manually into a repository.  However, if you are planning to load them through configuration you can read – Loading a configuration set of hooks into repository

      Step 2 – Getting a IHook Object from repository

       

      Method One – Getting hook object of a specific type

       

      Getting hook by Type
      [TestMethod] public void Test_Standard_GetHookByType()
      {
          var hooksRetrieved = hookRepository.Get(typeof(LogHook));
          Assert.AreEqual(1, hooksRetrieved.Length);
      }

       

      The above method will return all the hooks that match the type of LogHook.  Now say for example, the repository was created using code below

      Two hooks of same type
      LogHook logHook1 = new LogHook(); /* Default Guid, Name */
      LogHook logHook2 = new LogHook();
      logHook2.Name = "LogHook2";

      hookRepository.Add(new[] { logHook1, logHook2 });

       

      The code hookRepository.Get(typeof(LogHook)); would return the value 2.

      Method Two – Getting hook object based on some condition

       

      Getting hook by a predicate
      [TestMethod] public void Test_Standard_GetHookByName()
      {
          var hooksRetrieved = hookRepository.Get(x => x.Name != null && x.Name.Contains("Log"));
          Assert.AreEqual(1, hooksRetrieved.Length);
      }

      Using the above method, you can query on the hook collection and returns the hook objects in an IEnumerable collection.

      Method Three – Getting all hooks in a repository

      This is fairly simple.  You can access the collection Hooks in the repository to get all the hooks added in the repository

      Getting all hooks
      [TestMethod] public void Test_Standard_GetAllHooks()
      {
          var hooksRetrieved = hookRepository.Hooks;
          Assert.AreEqual(2, hooksRetrieved.Length);
      }

      dI.Hook – How to invoke hooks that satisfy a condition?

      August 1, 2012 Applications, CSharp, Open Source , , ,

      If you are new to dI.Hook, please visit the di.Hook Product Page for Overview, Release Version and Source Code.

      Some posts you might want to read would be:

      1. How to create a HookRepository?
      2. How to add hooks to HookRepository?
      3. How to add hooks via configuration file to a HookRepository?
      4. How to invoke all hooks using dI.Hook?

      So this is the fifth article in the series which will deal with invoking all the hooks in the repository.  This article will be a deviation from the fourth article on invoking all hooks.

      Step 1 – Creating a repository and add hooks into a repository

      The first decision in creating a hook repository is to think whether you want to have lazy loading or not.  Once you have decided you can go through the steps – Creating a Hook Repository using dI.Hook

      Be selective in adding hooks into a repository if you plan to invoke all of them at one go.  If you are thinking of manually adding hooks to a repository, would suggest going through – Adding hooks manually into a repository.  However, if you are planning to load them through configuration you can read – Loading a configuration set of hooks into repository

      Step 2 – Invoking filtered hooks in the repository

       

      Variation One – InvokeWhere

      InvokeWhere takes 2 parameters. First – A predicate that returns Boolean value and input as IHook object. Second – Input parameters to the OnInvoke method of each hook.   The OnInvoke method of a hook is called only when the predicate returns true value.

      An example of this would be,

      InvokeWhere with predicate
      int invokedCount = hookRepository.InvokeWhere(x =>
      {
      if (x is IAdditionalInterface)
      {
      return (x as IAdditionalInterface).IQ == “IQ.001”;
      }
      return false;
      });

       

      Variation Two – InvokeWhen with a predicate that takes no input

       

      InvokeWhere takes 2 parameter. First – A predicate that returns Boolean value without any input. Second – Input parameters to the OnInvoke method of each hook.   The OnInvoke method of a hook is called only when the predicate returns true value.

      An example of this would be,

      InvokeWhen with predicate
      int invokedCount = hookRepository.InvokeWhen(() =>
      {
      return false;
      });

       

      Variation Three – InvokeWhen with a predicate that takes no input, another that takes IHook object

      InvokeWhere takes 3 parameter. First – A predicate that returns Boolean value without any input. Second – predicate that returns Boolean value and input as IHook object. Third – Input parameters to the OnInvoke method of each hook.   The OnInvoke method of a hook is called only when both the predicates return true value.

      An example of this would be,

      InvokeWhen with 2 predicates
      int invokedCount = hookRepository.InvokeWhen(() => { return true; },
      (x) =>        {
      if (x is IAdditionalInterface)
      {
      return (x as IAdditionalInterface).IQ == “IQ.001”;
      }
      return false;
      });

       

      So using InvokeWhere and InvokeWhen you can filter the hooks to be invoked.

      How to invoke all hooks using dI.Hook?

      August 1, 2012 Applications, CSharp, Open Source , , ,

       

      If you are new to dI.Hook, please visit the di.Hook Product Page for Overview, Release Version and Source Code.

      Some posts you might want to read would be:

      1. How to create a HookRepository?
      2. How to add hooks to HookRepository?
      3. How to add hooks via configuration file to a HookRepository?

      So this is the fourth article in the series which will deal with invoking all the hooks in the repository.  This article will be short and simple as there are no two ways of invoking all the hooks in a repository.

      Step 1 – Creating a repository and add hooks into a repository

       

      The first decision in creating a hook repository is to think whether you want to have lazy loading or not.  Once you have decided you can go through the steps – Creating a Hook Repository using dI.Hook

      Be selective in adding hooks into a repository if you plan to invoke all of them at one go.  If you are thinking of manually adding hooks to a repository, would suggest going through – Adding hooks manually into a repository.  However, if you are planning to load them through configuration you can read – Loading a configuration set of hooks into repository

      Step 2 – Invoking all the hooks in the repository

       

      The code is fairly simple.  In fact, just one line

      Invoking all hooks
      int invokedCount = hookRepository.InvokeAll();

       

      The above code will call OnInvoke() of all the hooks without any parameters.  But how often would you have a scenario when you would have a hook with no parameters? I mean a system that does not take any input and gives no output. A black box! Oh, I haven’t seen such systems.  Most of the complexity in systems involve either communication between other systems in the ecosystem or in executing complex logic involving lot of workflows and rules.

      So hooks with no inputs and no outputs – not useful in many scenarios!

      InvokeAll with Parameters
      int invokedCount = hookRepository.InvokeAll("CalledByTestWithDifferentValues", 2);

       

      More parameters – not an issue!  You can add N-parameters each of different type and it would work flawlessly!

      So far, so good!

      But this code does not necessarily is performance centric. I mean, it does not really leverage the benefit of multi-core 64-bit processor and higher gig-RAM.  So we must optimize this to have some kind of parallel execution and spawning of threads. With .NET 4.0, we can ease this task using TPL – Read Parallel Programming in .NET 4.0 for more statistics.  So here’s the version that executes invoke of all hooks in parallel.

      InvokeAllAsParallel Example
      int invokedCount = hookRepository.InvokeAllAsParallel("CalledByTestWithDifferentValues", 2);

      Now that works great!

      OKay, one last word before we reach to the end of this article.  Now all invoke methods return an Int32 value.  This Int32 value represents the number of hooks whose OnInvoke executed successfully!

      Does it mean that there are chances that not all hooks will be executed? Yes.  Let’s see that taking some examples

      Invoke – With Exceptions
      [TestMethod] [ExpectedException(typeof(InvalidOperationException))] public void Test_Standard_InvokeAllWithExceptionRaisedInFirstHook()
      {
          // should block diagnostichook as well and throw exception
          int invokedCount = hookRepository.InvokeAll("RaiseLogException");
          Assert.AreEqual(0, invokedCount);
      }

      [TestMethod] [ExpectedException(typeof(InvalidOperationException))] public void Test_Standard_InvokeAllWithExceptionRaisedInSecondHook()
      {
          // should not block LogHook but should throw exception
          int invokedCount = hookRepository.InvokeAll("RaiseDiagnosticException");
          Assert.AreEqual(1, invokedCount);
      }

      In the method InvokeAllWithExceptionRaisedInFirstHook, assume that the LogHook throws an exception.  In the above case since DiagnosticsHook was added in the repository after LogHook (refer to article on How to Add Hooks), DiagnosticsHook is not called.  Hence the invokedCount = 0

      In the mehod InvokeAllWithExceptionRaisedInSecondHook, the LogHook does not throw an exception but DiagnosticsHook does.  Hence only LogHook gets executed leaving the value of invokedCount = 1

      Now lets see what happens when we use InvokeAsParallel

      InvokeAsParallel – Exceptions
      [TestMethod] [ExpectedException(typeof(AggregateException))] public void Test_Standard_InvokeAllAsParallelWithExceptionRaisedInFirstHook()
      {
          // will not block diagnostichook as it is parallel and will throw exception
          int invokedCount = hookRepository.InvokeAllAsParallel("RaiseLogException");
          Assert.AreEqual(1, invokedCount);
      }

      [TestMethod] [ExpectedException(typeof(AggregateException))] public void Test_Standard_InvokeAllAsParallelWithExceptionRaisedInSecondHook()
      {
          // will not block LogHook as it is parallel but should throw exception
          int invokedCount = hookRepository.InvokeAllAsParallel("RaiseDiagnosticException");
          Assert.AreEqual(1, invokedCount);
      }

       

      In the method InvokeAllWithExceptionRaisedInFirstHook, assume that the LogHook throws an exception. In the above case since DiagnosticsHook was added in the repository after LogHook (refer to article on How to Add Hooks) but it is executed in parallel, hence DiagnosticsHook is invoked.  This definitely means that an AggregateException will be thrown to calling method. Hence the invokedCount = 1

      In the mehod InvokeAllWithExceptionRaisedInSecondHook, the LogHook does not throw an exception but DiagnosticsHook does. Hence only LogHook gets executed leaving the value of invokedCount = 1

      To summarize, InvokeAll() method executes all hooks sequentially.  If any one fails, the following ones do not get executed.  InvokeAllAsParallel() method executes all hooks in parallel.  If any one fails, others still get executed.  Both methods will throw different exception messages to the calling method.

      In next article, we will explore how to invoke only specific hooks.

      dI.Hook – Load Hooks through Configuration

      July 30, 2012 Applications, CSharp, Open Source , , ,

       

      If you are new to dI.Hook, please visit the product page for Overview, Release Version and Source Code.

      One of the ways to adding hook(s ) in the HookRepository is to define them in Application Configuration file and then loading an appropriate configuration in repository.  The other ways are mentioned in How to Add Hooks in a Repository post

      Step 1 – Defining configuration

       

      Configuration – Sample
      <?xml version="1.0" encoding="utf-8" ?>
      <configuration>
        <configSections>
          <section name="dIHookConfiguration" type="dIHook.Configuration.dIHookConfigurationSection, dI.Hook"/>
        </configSections>
        <dIHookConfiguration>
          <repositories>
            <repository name="default" enabled="true">
              <hooks>
                <hook name="h1" type="dIHook.UnitTests.Hooks.LogHook, dI.Hook.UnitTests" />
                <hook name="h2" type="dIHook.UnitTests.Hooks.DiagnosticsHook, dI.Hook.UnitTests" />
              </hooks>
            </repository>
            <repository name="productionRepository" enabled="true">
              <hooks>
                <hook name="h2" type="dIHook.UnitTests.Hooks.DiagnosticsHook, dI.Hook.UnitTests" />
              </hooks>
            </repository>
            <repository name="productionRepositoryDisabled" enabled="false">
              <hooks>
                <hook name="h2" type="dIHook.UnitTests.Hooks.DiagnosticsHook, dI.Hook.UnitTests" />
              </hooks>
            </repository>
          </repositories>
        </dIHookConfiguration>
      </configuration>

      The above configuration has an element repositories that has multiple repository elements.

      A repository element has following attributes

      • Name: This represents a unique name of the repository.  A repository is fetched from configuration using this name.
      • Enabled: If the value is ‘false’ then that repository configuration is not considered when loading the configuration.  In the above configuration, when repository ‘productionRepositoryDisabled’ is loaded into a HookRepository it will not have any hooks.

        Each repository element represents a collection or container of hooks  elements.  Each hooks element has multiple hook elements.

        A hook element has multiple attributes

        • Name: Name of the hook
        • Type: Fully qualified type of the hook to be added to the repository.  This hook should inherit from IHook interface

          This relation can be summarized as:

          repositoryConfig

           

          Step 2 – Loading Configuration into Repository

           

          To load configuration of a repository with name ‘default’, the code is fairly simple

          Loading ‘default’ repository
          1. hookRepository.LoadConfiguration();

           

          To load a specific repository. Say, productionRepository from configuration from a section named ‘dIHookConfiguration’ in the ApplicationConfiguration the code should be

          Loading custom repository
          1. hookRepository.LoadConfiguration("dIHookConfiguration", "productionRepository");

          If the ‘enabled’ property of a repository is false, there will be no hooks added in the repository.  To verify this, you can try the code below

          Loading disabled repository
          [TestMethod] public void Test_Standard_LoadFromConfigFileWithRepositoryNameDisabled()
          {
              hookRepository.RemoveAll();
              hookRepository.LoadConfiguration("dIHookConfiguration", "productionRepositoryDisabled");

              Assert.AreEqual(0, hookRepository.Hooks.Length);
          }

          dI.Hook – How to add hooks to HookRepository?

          July 29, 2012 Applications, CSharp, Open Source , , ,

           

          If you are new to dI.Hook, please visit the product page for Overview, Release Version and Source Code.

          Hook – A hook is a .NET object derived from the interface IHook.  If you already have classes that have business/technical functionalities, implementing IHook will not impact their functionality.  If your classes have similar function names, it is advisable to explicitly implement interface IHook.

          To illustrate this, let’s create two hooks LogHook and DiagnosticsHook.  We will not focus on their implementation and limit our scope to their definition and adding them to HookRepository

          LogHook
          1. public class LogHook : IHook
          2.     {
          3.         public string Name { get; set; }
          4.         public Guid Id { get; set; }
          5.         public LogHook()
          6.         {
          7.             Name = "LogHook";
          8.             Id = new Guid("B3D75F63-F7DA-4939-8777-1A354202B9D2");
          9.         }
          10.  
          11.         public void OnInvoke(params object[] inputParams)
          12.         {
          13.             Console.WriteLine("Hook Called");
          14.         }
          15.  
          16.         public void Dispose()
          17.         {
          18.             Name = null;
          19.             Console.WriteLine("Woah! Hook Disposed!");
          20.         }
          21.     }

           

          DiagnosticsHook – Implements multiple interfaces (IHook, required for HookRepository) and IAdditionalInterface

          DiagnosticsHook
          1. public class DiagnosticsHook : IHook,
          2.         IAdditionalInterface
          3. {
          4.     public string Name { get; set; }
          5.     public Guid Id { get; set; }
          6.  
          7.     public DiagnosticsHook()
          8.     {
          9.         Name = "DiagnosticsHook";
          10.         Id = new Guid("CB75FCCF-593B-4BCF-871B-298087CDE741");
          11.     }
          12.  
          13.     public void OnInvoke(params object[] inputParams)
          14.     {
          15.         Console.WriteLine("Hook Called");
          16.     }
          17.  
          18.     public void Dispose()
          19.     {
          20.         Name = null;
          21.         Console.WriteLine("Woah! Hook Disposed!");
          22.     }
          23.  
          24.     public string IQ
          25.     {
          26.         get { return "IQ.001"; }
          27.     }
          28. }

           

           

          How to add an instance of a hook in a repository?

          When we are referring to adding an instance of a hook in a repository, there are multiple ways of doing it

          Method 1 – Adding one hook instance at a time

          Adding one hook at a time
          1. hookRepository.Add(new LogHook());
          2. hookRepository.Add(new DiagnosticsHook());

          Method 2 – Adding a List of hooks

          Adding a List of hooks
          1. hookRepository.Add(new List<IHook> { new LogHook(), new DiagnosticsHook()}) ;

          Method 3 – Adding two different instances of same hook type

          Adding 2 LogHooks
          1. LogHook logHook1 = new LogHook(); /* Default Guid */
          2. LogHook logHook2 = new LogHook();
          3. logHook2.Id = new Guid("B9D2D1E3-6BAD-47C3-AEFC-3ABFAAB210F8");
          4. hookRepository.Add(new[] { logHook1, logHook2 });

           

          Method 4 – Adding by searching within an Assembly

          Searching within an Assembly
          1. hookRepository.Add(SearchScope.CallingAssembly, SearchBy.Name, Operator.Like, "Log");

           

          Method 5 – Adding by searching within a directory

          Searching within a directory
          1. hookRepository.Add(SearchScope.CurrentDirectory, SearchBy.Name, Operator.Like, "Log");

           

          How to add a type of a hook in a repository?

           

          If your repository supports lazy loading, then adding a type of hook in a repository is preferred over adding an instance of a hook.   By adding a type in the repository, the instance of hook is not created until it is invoked or searched for.

          However, if your repository does not support lazy loading you can choose any mechanism of adding hook into repository

          Add a Hook Type in Repository
          1. hookRepository.Add(typeof(LogHook));
          2. hookRepository.Add(typeof(DiagnosticsHook));

           

          So you can add a hook by six different ways in a Hook Repository

          dI.Hook – How to create a HookRepository?

          July 29, 2012 Applications, CSharp, Open Source , , ,

           

          If you are new to dI.Hook, please visit the product page for Overview, Release Version and Source Code.

          What is hook and a repository?

           

          Hook – A hook is a .NET object derived from the interface IHook.  If you already have classes that have business/technical functionalities, implementing IHook will not impact their functionality.  If your classes have similar function names, it is advisable to explicitly implement interface IHook.

          Repository – A Container, or Collection of Hooks.  There are two types of repositories:

          • Standard Repository – HookRepository: This repository contains collection of instances of hooks
          • Lazy Repository – LazyHookRepository: This repository is a collection of type of hooks.  In this repository, the instance of a hook is created when it is invoked first time unless actually an instance is added explicitly.

          How to create a repository?

           

          Once you have decided the type of repository you want to create, you can choose one of the many ways of creating a repository

          Creating a repository using HookRepositoryFactory

           
          To create a LazyHookRepository, following code has to be written

          Creating a LazyHookRepository
          1. IHookRepository<IHook> repository =
          2. HookRepositoryFactory.Create<IHook>(true);

          To create a standard HookRepository,
           
          Creating a HookRepository
          1. IHookRepository<IHook> repository =
          2. HookRepositoryFactory.Create<IHook>(false);

           

          This repository is very light-weight and does not have any hooks in it.  So the next article would be to add hooks into this repository

          Follow on Feedly