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没有给出。需要进一步去学习)。。

你可能感兴趣的:(dynamic)