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沒有給出。需要進一步去學習)。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM