我想应用一些使用本地生长类型的“aspect”的行为,真的是.net属性。我有一个基础类(BankingServiceBase
),它在启动时反映自己,看看应用了哪些“方面”。然后它可以在操作之前或之后执行自定义行为。我使用Autofac作为我的IOC容器。我正在尝试将PropertiesAutowired方法应用于方面的注册。在下面的示例代码中,我希望Autofac为我的aspect/attribute注入一个ILog
实例。然而,它并没有这样做。我的猜测是,当我拨打GetCustomAttributes时,它会创建一个新实例,而不是从Autofac获取已注册的实例。思考?下面是一些可用的示例代码显示的问题:如何在.net属性中注入属性依赖关系?
internal class Program
{
private static void Main()
{
var builder = new ContainerBuilder();
builder
.RegisterType<ConsoleLog>()
.As<ILog>();
builder
.RegisterType<BankingService>()
.As<IBankingService>();
builder
.RegisterType<LogTransfer>()
.As<LogTransfer>()
.PropertiesAutowired();
var container = builder.Build();
var bankingService = container.Resolve<IBankingService>();
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<BankingServiceAspect> 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<BankingServiceAspect>().
ToList();
}
void IBankingService.Transfer(string from, string to, decimal amount)
{
aspects.ForEach(a => a.PreTransfer(from, to, amount));
try
{
Transfer(from, to, amount);
aspects.ForEach(a => a.PostTransfer(true));
}
catch (Exception)
{
aspects.ForEach(a => 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);
}
}
}
-1为什么在世界上,你会想要写一个类反思自己?有几个容器通过截取框来支持AOP。就[快速谷歌搜索显示](http://code.google.com/p/autofac/wiki/DynamicProxy2)Autofac也支持这一点。 – 2012-02-22 10:03:42