Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I am using reflection to accomplish this (and other) tasks. Let me show how that works.</p> <p>The first thing to do is to define an interface that allows us to identify classes that perform initialization tasks:</p> <pre><code>public interface IConfigurationTask { void Configure(); } </code></pre> <p>Next, create one or more classes that implement this interface. These classes will be spread across all of your projects, which is another way of saying that you can put them "where they belong".</p> <pre><code>public class RepositoryInitializer : IConfigurationTask { public void Configure() { // code that does relevant initialization goes here } } </code></pre> <p>The last piece of the puzzle is to find classes that implement the IConfigurationTask interface, create an instance of them and execute the Configure method. This is the purpose of the ConfigurationTaskRunner:</p> <pre><code>public static class ConfigurationTaskRunner { public static void Execute( params string[] assemblyNames ) { var assemblies = assemblyNames.Select( Assembly.Load ).Distinct().ToList(); Execute( assemblies ); } public static void Execute( IEnumerable&lt;Assembly&gt; assemblies ) { var tasks = new List&lt;IConfigurationTask&gt;(); assemblies.ForEach( a =&gt; tasks.AddRange( a.CreateInstances&lt;IConfigurationTask&gt;() ) ); tasks.ForEach( t =&gt; t.Configure() ); } } </code></pre> <p>The code shown here uses a custom extension to iterate over all items in a list and execute an action for every item (the ForEach method). I am also using a <a href="http://fasterflect.codeplex.com" rel="nofollow">reflection library</a> to make the task of locating and instantiating the instances a one-liner (the CreateInstances method), but you could achieve the same using just plain reflection (as shown in the code below).</p> <pre><code>public static IList&lt;T&gt; CreateInstances&lt;T&gt;( this Assembly assembly ) { var query = from type in assembly.GetTypes().Where( t =&gt; typeof(T).IsAssignableFrom( t ) &amp;&amp; typeof(T) != t ) where type.IsClass &amp;&amp; ! type.IsAbstract &amp;&amp; type.GetConstructor( Type.EmptyTypes ) != null select (T) Activator.CreateInstance( type ); return query.ToList(); } </code></pre> <p>The final piece of the puzzle is to trigger the execution of the ConfigurationTaskRunner. For example, in a web application this would go into Application_Start in Global.asax:</p> <pre><code>// pass in the names of the assemblies we want to scan, hardcoded here as an example ConfigurationTaskRunner.Execute( "Foo.dll", "Foo.Domain.dll" ); </code></pre> <p>I've also found it useful with a derived IPrioritizedConfigurationTask (that adds a Priority property) to allow proper ordering of the tasks before you execute them. This is not shown in the example code above, but is fairly trivial to add.</p> <p>Hope this helps!</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload