如何正确地将横切关注点应用于AbstractFactory创建的类?

时间:2014-08-07 07:50:53

标签: c# dependency-injection unity-container aop cross-cutting-concerns

我将IOC容器配置为添加交叉问题,但这些问题没有添加到AbstractFactories构造的类中。

public static void Main(string[] args)
{
    IUnityContainer container = new UnityContainer();
    container = Microsoft.Practices.Unity.Configuration.UnityContainerExtensions.LoadConfiguration(container);
    container.RegisterType<IApplication, MyApplication>();
    container.RegisterType<IUserStoreFactory, MyUserStoreFactory>();
    container.RegisterType<IUserStore, MyUserStore>();

    var app = container.Resolve<IApplication>();
    app.Run();
}
public interface IApplication
{
    void Run();
}

public class MyApplication : IApplication
{
    private readonly IUserStoreFactory userStoreFactory;

    public MyApplication(IUserStoreFactory userStoreFactory)
    {
        Debug.Assert(null != userStoreFactory, "UserFactory is required to construct user store.");
        this.userStoreFactory = userStoreFactory;
    }

    public void Run()
    {
        Console.Write("Enter user id: ");
        var userId = Console.ReadLine();
        var userStore = this.userStoreFactory.Create(userId);

        Console.Write("Enter user name: ");
        var userName = Console.ReadLine();

        userStore.Put("name", new { Name = userName });

        var obj = userStore.Get("name");

        Console.WriteLine(obj);
    }
}

public interface IUserStoreFactory
{
    IUserStore Create(string userId);
}

public class MyUserStoreFactory : IUserStoreFactory
{
    public IUserStore Create(string userId)
    {
        return new MyUserStore(userId);
    }
}

public interface IUserStore
{
    void Put(string key, object obj);

    object Get(string key);
}

public class MyUserStore : IUserStore
{
    private readonly string userId;

    public MyUserStore(string userId)
    {
        this.userId = userId;
    }

    public void Put(string key, object obj)
    {
        // Hard coding this dependency for the sake of simplicity.
        GlobalStore.Put(this.userId + key, obj);
    }

    public object Get(string key)
    {
        // Hard coding this dependency for the sake of simplicity.
        return GlobalStore.Get(this.userId + key);
    }
}

public static class GlobalStore
{
    private static readonly Dictionary<string, object> store = new Dictionary<string, object>();

    public static void Put(string key, object obj)
    {
        store[key] = obj;
    }

    public static object Get(string key)
    {
        return store[key];
    }
}

public class LoggingInterceptionBehavior : IInterceptionBehavior
{
    public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
    {
        Console.WriteLine("Before method execution : {0} | {1}", input.Target, input.MethodBase);
        IMethodReturn msg = getNext()(input, getNext);
        Console.WriteLine("After method execution : {0} | {1}", input.Target, input.MethodBase);
        return msg;
    }

    public IEnumerable<Type> GetRequiredInterfaces()
    {
        return Type.EmptyTypes;
    }

    public bool WillExecute
    {
        get
        {
            return true;
        }
    }
}

拦截器在配置文件中定义为:

<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">

<alias alias="IApplication" type="AbstractFactoryInterceptionTest.IApplication, AbstractFactoryInterceptionTest"/>
<alias alias="IUserStore" type="AbstractFactoryInterceptionTest.IUserStore, AbstractFactoryInterceptionTest"/>
<alias alias="MyUserStore" type="AbstractFactoryInterceptionTest.MyUserStore, AbstractFactoryInterceptionTest"/>
<alias alias="LoggingInterceptionBehavior" type="AbstractFactoryInterceptionTest.LoggingInterceptionBehavior, AbstractFactoryInterceptionTest" />

<sectionExtension
   type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension,  
         Microsoft.Practices.Unity.Interception.Configuration" />

<container>
  <extension type="Interception"/>
  <register type="IApplication">
    <interceptor type="InterfaceInterceptor" />
    <interceptionBehavior type="LoggingInterceptionBehavior"/>
  </register>
  <register type="IUserStore">
    <interceptor type="InterfaceInterceptor" />
    <interceptionBehavior type="LoggingInterceptionBehavior"/>
  </register>
</container>

已为IApplication和IUserStore定义了LoggingInterceptor。但是如果您运行代码,您可以看到IUserStore没有被截获(因为它没有通过Unity解析)。

以下是上述程序的输出:

Before method execution : AbstractFactoryInterceptionTest.MyApplication | Void Run()
Enter user id: 123
Enter user name: Arnab
{ Name = Arnab }
After method execution : AbstractFactoryInterceptionTest.MyApplication | Void Run()

如何修改此代码,以便拦截器也应用于工厂构造的对象?

0 个答案:

没有答案