/src/LinFu.IoC/Configuration/Loaders/PostProcessorLoader.cs
C# | 79 lines | 44 code | 8 blank | 27 comment | 6 complexity | 2c41cade1560f922bba31bbed1cc5c74 MD5 | raw file
1using System; 2using System.Collections.Generic; 3using System.IO; 4using System.Linq; 5using LinFu.IoC.Interfaces; 6using LinFu.Reflection; 7 8namespace LinFu.IoC.Configuration.Loaders 9{ 10 /// <summary> 11 /// A class that automatically loads <see cref="IPostProcessor" /> 12 /// instances and configures a loader to inject those postprocessors 13 /// into a container upon initialization. 14 /// </summary> 15 internal class PostProcessorLoader : IActionLoader<IServiceContainer, Type> 16 { 17 /// <summary> 18 /// Determines if the plugin loader can load the <paramref name="inputType" />. 19 /// </summary> 20 /// <remarks> 21 /// The target type must implement the <see cref="IPostProcessor" /> interface before it can be loaded into 22 /// memory. 23 /// </remarks> 24 /// <param name="inputType">The target type that might contain the target instance.</param> 25 /// <returns><c>true</c> if the type can be loaded; otherwise, it returns <c>false</c>.</returns> 26 public bool CanLoad(Type inputType) 27 { 28 try 29 { 30 // The type must have a default constructor 31 var defaultConstructor = inputType.GetConstructor(new Type[0]); 32 if (defaultConstructor == null) 33 return false; 34 35 // It must have the PostProcessorAttribute defined 36 var attributes = inputType.GetCustomAttributes(typeof(PostProcessorAttribute), true); 37 var attributeList = attributes.Cast<PostProcessorAttribute>(); 38 39 if (attributeList.Count() == 0) 40 return false; 41 42 return typeof(IPostProcessor).IsAssignableFrom(inputType); 43 } 44 catch (TypeInitializationException) 45 { 46 // Ignore the error 47 return false; 48 } 49 catch (FileNotFoundException) 50 { 51 // Ignore the error 52 return false; 53 } 54 } 55 56 /// <summary> 57 /// Loads a set of <see cref="IPostProcessor" /> instances 58 /// so that they can be loaded into a container upon initialization. 59 /// </summary> 60 /// <param name="inputType">The type that will be used to configure the target loader.</param> 61 /// <returns>A set of <see cref="Action{TTarget}" /> instances. This cannot be <c>null</c>.</returns> 62 public IEnumerable<Action<IServiceContainer>> Load(Type inputType) 63 { 64 var defaultResult = new Action<IServiceContainer>[0]; 65 66 // Create the postprocessor instance 67 var instance = Activator.CreateInstance(inputType) as IPostProcessor; 68 if (instance == null) 69 return defaultResult; 70 71 // Inject the postprocessor into any service containers 72 // that will be configured by the current loader instance 73 Action<IServiceContainer> assignPostProcessor = 74 container => container.PostProcessors.Add(instance); 75 76 return new[] {assignPostProcessor}; 77 } 78 } 79}