title: How to inject property dependencies on a .net attribute?
body: <p>I'm trying to apply some behavior using a home grown type of "aspect", really a .net Attribute. I have a base class (<code>BankingServiceBase</code>) that reflects on itself at startup to see what "aspects" are applied to it. It then can execute custom behavior before or after operations. I'm using Autofac as my IOC container. I'm trying to apply the <a href="http://code.google.com/p/autofac/wiki/PropertyInjection" rel="nofollow">PropertiesAutowired</a> method to the aspect's registration. In the below sample code I want Autofac to inject an <code>ILog</code> instance to my aspect/attribute. It isn't doing that however. My guess is that when I call <a href="http://msdn.microsoft.com/en-us/library/aa330172%28v=vs.71%29.aspx" rel="nofollow">GetCustomAttributes</a>, it's creating a new instance instead of getting the registered instance from Autofac. Thoughts? Here is some usable sample code to display the problem:</p>
  
  <pre><code>internal class Program
  {
      private static void Main()
      {
          var builder = new ContainerBuilder();
  
          builder
              .RegisterType&lt;ConsoleLog&gt;()
              .As&lt;ILog&gt;();
  
          builder
              .RegisterType&lt;BankingService&gt;()
              .As&lt;IBankingService&gt;();
  
          builder
              .RegisterType&lt;LogTransfer&gt;()
              .As&lt;LogTransfer&gt;()
              .PropertiesAutowired();
  
          var container = builder.Build();
  
          var bankingService = container.Resolve&lt;IBankingService&gt;();
  
          bankingService.Transfer("ACT 1", "ACT 2", 180);
  
          System.Console.ReadKey();
      }
  
      public interface IBankingService
      {
          void Transfer(string from, string to, decimal amount);
      }
  
      public interface ILog
      {
          void LogMessage(string message);
      }
  
      public class ConsoleLog : ILog
      {
          public void LogMessage(string message)
          {
              System.Console.WriteLine(message);
          }
      }
  
      [AttributeUsage(AttributeTargets.Class)]
      public abstract class BankingServiceAspect : Attribute
      {
          public virtual void PreTransfer(string from, string to, decimal amount)
          {
          }
  
          public virtual void PostTransfer(bool success)
          {
          }
      }
  
      public class LogTransfer : BankingServiceAspect
      {
          // Note: this is never getting set from Autofac!
          public ILog Log { get; set; }
  
          public override void PreTransfer(string from, string to, decimal amount)
          {
              Log.LogMessage(string.Format("About to transfer from {0}, to {1}, for amount {2}", from, to, amount));
          }
  
          public override void PostTransfer(bool success)
          {
              Log.LogMessage(success ? "Transfer completed!" : "Transfer failed!");
          }
      }
  
      public abstract class BankingServiceBase : IBankingService
      {
          private readonly List&lt;BankingServiceAspect&gt; aspects;
  
          protected BankingServiceBase()
          {
              // Note: My guess is that this "GetCustomAttributes" is happening before the IOC dependency map is built.
              aspects =
                  GetType().GetCustomAttributes(typeof (BankingServiceAspect), true).Cast&lt;BankingServiceAspect&gt;().
                      ToList();
          }
  
          void IBankingService.Transfer(string from, string to, decimal amount)
          {
              aspects.ForEach(a =&gt; a.PreTransfer(from, to, amount));
  
              try
              {
                  Transfer(from, to, amount);
                  aspects.ForEach(a =&gt; a.PostTransfer(true));
              }
              catch (Exception)
              {
                  aspects.ForEach(a =&gt; a.PostTransfer(false));
              }
          }
  
          public abstract void Transfer(string from, string to, decimal amount);
      }
  
      [LogTransfer]
      public class BankingService : BankingServiceBase
      {
          public override void Transfer(string from, string to, decimal amount)
          {
              // Simulate some latency..
              Thread.Sleep(1000);
          }
      }
  }
  </code></pre>