Autofac整合Castle.DynamicProxy实现AOP

1.官网的例子有一些问题。自己学习总结下并且重新打包一个版本供学习。

 

1.AttributedInterfaceInterceptionFixture

[TestFixture]
    public class AttributedInterfaceInterceptionFixture
    {
        [Intercept(typeof(AddOneInterceptor))]
        public interface IHasI
        {
            int GetI();
        }

        public class C : IHasI
        {
            public int I { get; private set; }

            public C()
            {
                I = 10;
            }

            public int GetI()
            {
                return I;
            }
        }

        class AddOneInterceptor : IInterceptor
        {
            public void Intercept(IInvocation invocation)
            {
                invocation.Proceed();
                if (invocation.Method.Name == "GetI")
                    invocation.ReturnValue = 1 + (int)invocation.ReturnValue;
            }
        }

        [Test]
        public void DetectsNonInterfaceServices()
        {
            var builder = new ContainerBuilder();
            builder.RegisterType<C>().EnableInterfaceInterceptors();
            builder.RegisterType<AddOneInterceptor>();
            var c = builder.Build();
            var dx = Assert.Throws<DependencyResolutionException>(() => c.Resolve<C>());
            Assert.IsInstanceOf<InvalidOperationException>(dx.InnerException);
        }

        [Test]
        public void FindsInterceptionAttributeOnReflectionComponent()
        {
            var builder = new ContainerBuilder();
            builder.RegisterType<C>().As<IHasI>().EnableInterfaceInterceptors();
            builder.RegisterType<AddOneInterceptor>();
            var cpt = builder.Build().Resolve<IHasI>();

            Assert.AreEqual(11, cpt.GetI()); // proxied
        }

        [Test]
        public void FindsInterceptionAttributeOnExpressionComponent()
        {
            var builder = new ContainerBuilder();
            builder.Register(c => new C()).As<IHasI>().EnableInterfaceInterceptors();
            builder.RegisterType<AddOneInterceptor>();
            var cpt = builder.Build().Resolve<IHasI>();

            Assert.AreEqual(11, cpt.GetI()); // proxied
        }
    }

 

2.ClassInterceptorsFixture

[TestFixture]
    public class ClassInterceptorsFixture
    {
        [Intercept(typeof(AddOneInterceptor))]
        public class C
        {
            public int I { get; set; }

            public C(int i)
            {
                I = i;
            }

            public virtual int GetI()
            {
                return I;
            }
        }

        class AddOneInterceptor : IInterceptor
        {
            public void Intercept(IInvocation invocation)
            {
                invocation.Proceed();
                if (invocation.Method.Name == "GetI")
                    invocation.ReturnValue = 1 + (int)invocation.ReturnValue;
            }
        }

        [Test]
        public void InterceptsReflectionBasedComponent()
        {
            var builder = new ContainerBuilder();
            builder.RegisterType<C>().EnableClassInterceptors();
            builder.RegisterType<AddOneInterceptor>();
            var container = builder.Build();
            var i = 10;
            var c = container.Resolve<C>(TypedParameter.From(i));
            var got = c.GetI();
            Assert.AreEqual(i + 1, got);
        }
    }

 

3.InterceptorsChosenByMetadataFixture

 

[TestFixture]
    public class InterceptorsChosenByMetadataFixture
    {
        public interface ICustomerService
        {
            int GetVisitCount();
        }

        public class CustomerService : ICustomerService
        {
            int VisitCount { get; set; }

            public CustomerService()
            {
                VisitCount = 10;
            }

            public int GetVisitCount()
            {
                return VisitCount;
            }
        }

        class AddOneInterceptor : IInterceptor
        {
            public void Intercept(IInvocation invocation)
            {
                invocation.Proceed();
                if (invocation.Method.Name.StartsWith("Get"))
                    invocation.ReturnValue = 1 + (int)invocation.ReturnValue;
            }
        }

        [Test]
        public void InterceptsWhenUsingExtendedPropertyAndType()
        {
            var builder = new ContainerBuilder();
            builder.RegisterType<CustomerService>()
                .As<ICustomerService>()
                .EnableInterfaceInterceptors()
                .InterceptedBy(typeof(AddOneInterceptor));
            builder.RegisterType<AddOneInterceptor>();
            var container = builder.Build();
            var cs = container.Resolve<ICustomerService>();
            Assert.AreEqual(11, cs.GetVisitCount());
        }
    }

 

4.InterfaceInterceptorsFixture

[TestFixture]
    public class InterfaceInterceptorsFixture
    {
        [Test(Description = "Interception should not be able to occur against internal interfaces.")]
        public void DoesNotInterceptInternalInterfaces()
        {
            // DynamicProxy2 only supports visible interfaces so internal won't work.
            var builder = new ContainerBuilder();
            builder.RegisterType<StringMethodInterceptor>();
            builder
                .RegisterType<Interceptable>()
                .EnableInterfaceInterceptors()
                .InterceptedBy(typeof(StringMethodInterceptor))
                .As<IInternalInterface>();
            var container = builder.Build();
            var dre = Assert.Throws<DependencyResolutionException>(() => container.Resolve<IInternalInterface>());
            Assert.IsInstanceOf<InvalidOperationException>(dre.InnerException, "The inner exception should explain about public interfaces being required.");
        }

        [Test(Description = "Interception should be able to occur against public interfaces.")]
        public void InterceptsPublicInterfaces()
        {
            var builder = new ContainerBuilder();
            builder.RegisterType<StringMethodInterceptor>();
            builder
                .RegisterType<Interceptable>()
                .EnableInterfaceInterceptors()
                .InterceptedBy(typeof(StringMethodInterceptor))
                .As<IPublicInterface>();
            var container = builder.Build();
            var obj = container.Resolve<IPublicInterface>();
            Assert.AreEqual("intercepted-PublicMethod", obj.PublicMethod(), "The interface method should have been intercepted.");
        }

        public class Interceptable : IPublicInterface, IInternalInterface
        {
            public string PublicMethod()
            {
                throw new NotImplementedException();
            }

            public string InternalMethod()
            {
                throw new NotImplementedException();
            }
        }

        public interface IPublicInterface
        {
            string PublicMethod();
        }

        internal interface IInternalInterface
        {
            string InternalMethod();
        }

        private class StringMethodInterceptor : IInterceptor
        {
            public void Intercept(IInvocation invocation)
            {
                if (invocation.Method.ReturnType == typeof(string))
                {
                    invocation.ReturnValue = "intercepted-" + invocation.Method.Name;
                }
                else
                {
                    invocation.Proceed();
                }
            }
        }

    }

 

代码下载: AopDemo

 

总结: 相对于spring.net繁琐的API和大量XML, Autofac&DynamicProxy 提供了又一种轻量级IOC&AOP解决方案。要说不足的地方。 与当前主流技术(如WCF,MVC,ORM)整合稍弱一些(也有可能可以很好整合,只是官方Demo没有给出。需要进一步去学习)。。

posted @ 2013-01-10 22:11  不夜橙  阅读(8572)  评论(6编辑  收藏  举报