私は自宅で栽培された "アスペクト"タイプのもの、実際は.net属性を使っていくつかの動作を適用しようとしています。私は起動時に "aspect"がどのように適用されているかを見るためにそれ自身を反映する基本クラス(BankingServiceBase
)を持っています。その後、操作の前または後にカスタム動作を実行できます。私はIOCコンテナとしてAutofacを使用しています。私は、アスペクトの登録にPropertiesAutowiredメソッドを適用しようとしています。以下のサンプルコードでは、AutofacがILog
インスタンスを自分のアスペクト/属性に挿入します。しかしそれはやっていません。私の推測では、GetCustomAttributesと呼ぶと、登録されたインスタンスをAutofacから取得するのではなく、新しいインスタンスが作成されているということです。思考?側面プロパティの依存関係を.net属性に挿入する方法は?
private readonly List<BankingServiceAspect> _aspects;
private List<BankingServiceAspect> Aspects
{
get
{
if (_aspects == null) {
_aspects = GetType()
.GetCustomAttributes(typeof(BankingServiceAspect), true)
.Cast<BankingServiceAspect>()
.ToList();
}
return _aspects;
}
}
の遅延ロードを実装するために
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もサポートしています。 –