/src/LinFu.Reflection/BasePluginLoader.cs

http://github.com/philiplaureano/LinFu · C# · 57 lines · 32 code · 4 blank · 21 comment · 2 complexity · 7e0fed204ecfc7f9ca05a0ecea9bd7d6 MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. namespace LinFu.Reflection
  6. {
  7. /// <summary>
  8. /// Implements the basic functionality of a plugin loader.
  9. /// </summary>
  10. /// <typeparam name="TTarget">The target type being configured.</typeparam>
  11. /// <typeparam name="TAttribute">The attribute type that will be used to mark a type as a plugin.</typeparam>
  12. public abstract class BasePluginLoader<TTarget, TAttribute> : IActionLoader<ILoader<TTarget>, Type>
  13. where TAttribute : Attribute
  14. {
  15. /// <summary>
  16. /// Determines if the plugin loader can load the <paramref name="inputType" />.
  17. /// </summary>
  18. /// <param name="inputType">The target type that might contain the target <typeparamref name="TAttribute" /> instance.</param>
  19. /// <returns><c>true</c> if the type can be loaded; otherwise, it returns <c>false</c>.</returns>
  20. public virtual bool CanLoad(Type inputType)
  21. {
  22. try
  23. {
  24. var attributes = inputType.GetCustomAttributes(typeof(TAttribute), true)
  25. .Cast<TAttribute>();
  26. // The type must have a default constructor
  27. var defaultConstructor = inputType.GetConstructor(new Type[0]);
  28. if (defaultConstructor == null)
  29. return false;
  30. // The target must implement the ILoaderPlugin<TTarget> interface
  31. // and be marked with the custom attribute
  32. return attributes.Count() > 0;
  33. }
  34. catch (TypeInitializationException)
  35. {
  36. // Ignore the error
  37. return false;
  38. }
  39. catch (FileNotFoundException)
  40. {
  41. // Ignore the error
  42. return false;
  43. }
  44. }
  45. /// <summary>
  46. /// Generates a set of <see cref="Action{TTarget}" /> instances
  47. /// using the given <paramref name="input" />.
  48. /// </summary>
  49. /// <param name="input">The input that will be used to configure the target.</param>
  50. /// <returns>A set of <see cref="Action{TTarget}" /> instances. This cannot be <c>null</c>.</returns>
  51. public abstract IEnumerable<Action<ILoader<TTarget>>> Load(Type input);
  52. }
  53. }