让 SNAP AOP 框架与 Ninject MVC 3 一起使用

发布于 2024-12-11 02:27:45 字数 7849 浏览 0 评论 0原文

我想在我的 MVC3 应用程序中使用 Snap 尝试 SOA 风格的日志记录。我使用 Ninject 进行 IoC,因此通过 Nuget 安装了 Ninject.MVC 和 Snap.Ninject,所有这些都查看了 GitHub 中 Snap.Ninject 的示例代码。我还阅读了 获取 SNAP(AOP) 、NInject 和 ASP.Net MVC 3 协同工作 这似乎正是我想要的。

我已相应地更新了 NinjctMVC3.cs,但是当我将拦截器属性添加到我的方法时,我从 Snap AspectUtility 收到对象引用错误。这是我的 NinjectMVC3.cs

    public static class NinjectMVC3 {
    private static readonly Bootstrapper bootstrapper = new Bootstrapper();

    /// <summary>
    /// Starts the application
    /// </summary>
    public static void Start() {
        DynamicModuleUtility.RegisterModule(typeof(OnePerRequestModule));
        DynamicModuleUtility.RegisterModule(typeof(HttpApplicationInitializationModule));
        bootstrapper.Initialize(CreateKernel);
    }

    /// <summary>
    /// Stops the application.
    /// </summary>
    public static void Stop() {
        bootstrapper.ShutDown();
    }

    /// <summary>
    /// Creates the kernel that will manage your application.
    /// </summary>
    /// <returns>The created kernel.</returns>
    private static IKernel CreateKernel() {
        //var kernel = new StandardKernel();
        NinjectAopConfiguration.NinjectAopConfigure();
        var kernel = NinjectAopConfiguration._container.Kernel;
        RegisterServices(kernel);
        return kernel;
    }

    /// <summary>
    /// Load your modules or register your services here!
    /// </summary>
    /// <param name="kernel">The kernel.</param>
    private static void RegisterServices(IKernel kernel) {

        kernel.Bind<ILogger>().To<NLogger>()
            .WithConstructorArgument("currentClassName", x => x.Request.ParentContext.Request.Service.FullName); ;
        kernel.Bind<ISomeDataFactory>().To<SomeDataFactory>();
    }
}

public static class NinjectAopConfiguration {
    public readonly static NinjectAspectContainer _container;

    static NinjectAopConfiguration() {
        _container = new NinjectAspectContainer();
    }
    public static void NinjectAopConfigure() {
        SnapConfiguration.For(_container).Configure(c => {
            c.IncludeNamespace("TestAopLogging.Model.*");
            c.Bind<MyMethodInterceptor>().To<MyInterceptorAttribute>();
        });
    }
}

public class MyMethodInterceptor : MethodInterceptor {
    public override void InterceptMethod(Castle.DynamicProxy.IInvocation invocation, MethodBase method, System.Attribute attribute) {
        var logger = new NLogger(method.DeclaringType.ToString());
        logger.LogInfo("Hello AOP Logger. Your method (" + method.Name + ") has been intercepted");
        invocation.Proceed();
    }

    public override void BeforeInvocation() {
        var logger = new NLogger("How do I work out what class I'm in?");
        base.BeforeInvocation();
    }

    public override void AfterInvocation() {
        var logger = new NLogger("How do I work out what class I'm in?");
        logger.LogInfo("Hello AOP Logger. After Invocation");
        base.AfterInvocation();
    }
}

public class MyInterceptorAttribute : MethodInterceptAttribute { }

以及带有拦截属性的方法的控制器

 public class HomeController : Controller
{
    private ILogger _logger;
    private ISomeDataFactory _someDataFactory;

    public HomeController(ILogger logger, ISomeDataFactory someDataFactory) {
        _logger = logger;
        _someDataFactory = someDataFactory;
    }


    public ActionResult Index()
    {
        _logger.LogInfo("I've hit the index action");
        _someDataFactory.GetStuffAndLogTheOldWay();
        _someDataFactory.GetStuffAndLogUsingAOP();
        ViewBag.Message = "Welcome to ASP.NET MVC!";

        return View();
    }

    public ActionResult About()
    {
        return View();
    }
}

和工厂类

public interface ISomeDataFactory {
    string GetStuffAndLogTheOldWay();
    string GetStuffAndLogUsingAOP();
}

public class SomeDataFactory : ISomeDataFactory {
    private ILogger _logger;

    public SomeDataFactory(ILogger logger) {
        _logger = logger;
    }

    public string GetStuffAndLogTheOldWay() {
        _logger.LogInfo(MethodBase.GetCurrentMethod().Name + " was called");
        return "I called GetStuffAndLogTheOldWay";
    }

    [MyInterceptor] // If I comment this out, then all is good
    public string GetStuffAndLogUsingAOP() {
        return "I called GetStuffAndLogUsingAOP";
    }
}

,这会导致以下异常

[NullReferenceException:对象引用未设置为对象的实例。] Snap.AspectUtility.CreateProxy(类型interfaceType,对象instanceToWrap,IInterceptor []拦截器)+29 Snap.AspectUtility.CreatePseudoProxy(IMasterProxy代理,类型interfaceType,对象instanceToWrap)+184 Snap.Ninject.AspectProxyActivationStrategy.Activate(IContext上下文,InstanceReference参考)+376 Ninject.Activation。c__DisplayClass2.b__0(IActivationStrategy s) 在 c:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\Activation\Pipeline.cs:58 C:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\Infrastruct\Language\ExtensionsForIEnumerableOfT.cs 中的 Ninject.Infrastruct.Language.ExtensionsForIEnumerableOfT.Map(IEnumerable1 系列,Action1 操作) :23 Ninject.Activation.Pipeline.Activate(IContext 上下文,InstanceReference 引用)位于 c:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\Activation\Pipeline.cs:58 C:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\Activation\Context.cs 中的 Ninject.Activation.Context.Resolve():182 C:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\KernelBase.cs 中的 Ninject.KernelBase.b__7(IContext 上下文):375 System.Linq.<>c__DisplayClass123.b__11(TSource x) +32 System.Linq.WhereSelectEnumerableIterator2.MoveNext() +151 System.Linq.Enumerable.SingleOrDefault(IEnumerable1 源)+4178557 C:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\Planning\Targets\Target.cs 中的 Ninject.Planning.Targets.Target1.GetValue(类型服务,IContext 父级):179 C:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\Planning\Targets\Target.cs 中的 Ninject.Planning.Targets.Target1.ResolveWithin(IContext Parent):147 C:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:97 中的 Ninject.Activation.Providers.StandardProvider.GetValue(IContext 上下文,ITarget 目标) Ninject.Activation.Providers。<>c__DisplayClass2。<在 c:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:81 中创建>b__1(ITarget 目标) System.Linq.WhereSelectArrayIterator2.MoveNext() +85 System.Linq.Buffer1..ctor(IEnumerable1 源) +325 System.Linq.Enumerable.ToArray(IEnumerable1 源) +78 Ninject.Activation.Providers.StandardProvider.Create(IContext context) 在 c:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:81 C:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\Activation\Context.cs 中的 Ninject.Activation.Context.Resolve():157 C:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\KernelBase.cs 中的 Ninject.KernelBase.b__7(IContext context):375 System.Linq.<>c__DisplayClass123.b__11(TSource x) +32 System.Linq.WhereSelectEnumerableIterator2.MoveNext() +151 System.Linq.Enumerable.SingleOrDefault(IEnumerable1 源)+4178557 C:\Projects\Ninject\Maintenance2.2\ninject.web.mvc\mvc3\src\Ninject.Web.Mvc\NinjectDependencyResolver.cs 中的 Ninject.Web.Mvc.NinjectDependencyResolver.GetService(Type serviceType):56 System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext,类型controllerType)+51

提前致谢。我想要一个它失败的工作演示,然后让我知道。

I want to try out so SOA style logging using Snap in my MVC3 application. I'm using Ninject for IoC so have installed Ninject.MVC and Snap.Ninject via Nuget all had a look at the sample code in GitHub for Snap.Ninject. I also read Getting SNAP(AOP), NInject and ASP.Net MVC 3 working together
which seems to be doing exactly what I want.

I've updated my NinjctMVC3.cs accordingly but when I add the interceptor attribute to my method, I get an object ref error from Snap AspectUtility. Here is my NinjectMVC3.cs

    public static class NinjectMVC3 {
    private static readonly Bootstrapper bootstrapper = new Bootstrapper();

    /// <summary>
    /// Starts the application
    /// </summary>
    public static void Start() {
        DynamicModuleUtility.RegisterModule(typeof(OnePerRequestModule));
        DynamicModuleUtility.RegisterModule(typeof(HttpApplicationInitializationModule));
        bootstrapper.Initialize(CreateKernel);
    }

    /// <summary>
    /// Stops the application.
    /// </summary>
    public static void Stop() {
        bootstrapper.ShutDown();
    }

    /// <summary>
    /// Creates the kernel that will manage your application.
    /// </summary>
    /// <returns>The created kernel.</returns>
    private static IKernel CreateKernel() {
        //var kernel = new StandardKernel();
        NinjectAopConfiguration.NinjectAopConfigure();
        var kernel = NinjectAopConfiguration._container.Kernel;
        RegisterServices(kernel);
        return kernel;
    }

    /// <summary>
    /// Load your modules or register your services here!
    /// </summary>
    /// <param name="kernel">The kernel.</param>
    private static void RegisterServices(IKernel kernel) {

        kernel.Bind<ILogger>().To<NLogger>()
            .WithConstructorArgument("currentClassName", x => x.Request.ParentContext.Request.Service.FullName); ;
        kernel.Bind<ISomeDataFactory>().To<SomeDataFactory>();
    }
}

public static class NinjectAopConfiguration {
    public readonly static NinjectAspectContainer _container;

    static NinjectAopConfiguration() {
        _container = new NinjectAspectContainer();
    }
    public static void NinjectAopConfigure() {
        SnapConfiguration.For(_container).Configure(c => {
            c.IncludeNamespace("TestAopLogging.Model.*");
            c.Bind<MyMethodInterceptor>().To<MyInterceptorAttribute>();
        });
    }
}

public class MyMethodInterceptor : MethodInterceptor {
    public override void InterceptMethod(Castle.DynamicProxy.IInvocation invocation, MethodBase method, System.Attribute attribute) {
        var logger = new NLogger(method.DeclaringType.ToString());
        logger.LogInfo("Hello AOP Logger. Your method (" + method.Name + ") has been intercepted");
        invocation.Proceed();
    }

    public override void BeforeInvocation() {
        var logger = new NLogger("How do I work out what class I'm in?");
        base.BeforeInvocation();
    }

    public override void AfterInvocation() {
        var logger = new NLogger("How do I work out what class I'm in?");
        logger.LogInfo("Hello AOP Logger. After Invocation");
        base.AfterInvocation();
    }
}

public class MyInterceptorAttribute : MethodInterceptAttribute { }

And the controller

 public class HomeController : Controller
{
    private ILogger _logger;
    private ISomeDataFactory _someDataFactory;

    public HomeController(ILogger logger, ISomeDataFactory someDataFactory) {
        _logger = logger;
        _someDataFactory = someDataFactory;
    }


    public ActionResult Index()
    {
        _logger.LogInfo("I've hit the index action");
        _someDataFactory.GetStuffAndLogTheOldWay();
        _someDataFactory.GetStuffAndLogUsingAOP();
        ViewBag.Message = "Welcome to ASP.NET MVC!";

        return View();
    }

    public ActionResult About()
    {
        return View();
    }
}

and the factory class with the method with the intercept attribute

public interface ISomeDataFactory {
    string GetStuffAndLogTheOldWay();
    string GetStuffAndLogUsingAOP();
}

public class SomeDataFactory : ISomeDataFactory {
    private ILogger _logger;

    public SomeDataFactory(ILogger logger) {
        _logger = logger;
    }

    public string GetStuffAndLogTheOldWay() {
        _logger.LogInfo(MethodBase.GetCurrentMethod().Name + " was called");
        return "I called GetStuffAndLogTheOldWay";
    }

    [MyInterceptor] // If I comment this out, then all is good
    public string GetStuffAndLogUsingAOP() {
        return "I called GetStuffAndLogUsingAOP";
    }
}

and this results in the following exception

[NullReferenceException: Object reference not set to an instance of an object.]
Snap.AspectUtility.CreateProxy(Type interfaceType, Object instanceToWrap, IInterceptor[] interceptors) +29
Snap.AspectUtility.CreatePseudoProxy(IMasterProxy proxy, Type interfaceType, Object instanceToWrap) +184
Snap.Ninject.AspectProxyActivationStrategy.Activate(IContext context, InstanceReference reference) +376
Ninject.Activation.<>c__DisplayClass2.b__0(IActivationStrategy s) in c:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\Activation\Pipeline.cs:58
Ninject.Infrastructure.Language.ExtensionsForIEnumerableOfT.Map(IEnumerable1 series, Action1 action) in c:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\Infrastructure\Language\ExtensionsForIEnumerableOfT.cs:23
Ninject.Activation.Pipeline.Activate(IContext context, InstanceReference reference) in c:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\Activation\Pipeline.cs:58
Ninject.Activation.Context.Resolve() in c:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\Activation\Context.cs:182
Ninject.KernelBase.b__7(IContext context) in c:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\KernelBase.cs:375
System.Linq.<>c__DisplayClass123.<CombineSelectors>b__11(TSource x) +32
System.Linq.WhereSelectEnumerableIterator
2.MoveNext() +151
System.Linq.Enumerable.SingleOrDefault(IEnumerable1 source) +4178557
Ninject.Planning.Targets.Target
1.GetValue(Type service, IContext parent) in c:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\Planning\Targets\Target.cs:179
Ninject.Planning.Targets.Target1.ResolveWithin(IContext parent) in c:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\Planning\Targets\Target.cs:147
Ninject.Activation.Providers.StandardProvider.GetValue(IContext context, ITarget target) in c:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:97
Ninject.Activation.Providers.<>c__DisplayClass2.<Create>b__1(ITarget target) in c:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:81
System.Linq.WhereSelectArrayIterator
2.MoveNext() +85
System.Linq.Buffer1..ctor(IEnumerable1 source) +325
System.Linq.Enumerable.ToArray(IEnumerable1 source) +78
Ninject.Activation.Providers.StandardProvider.Create(IContext context) in c:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:81
Ninject.Activation.Context.Resolve() in c:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\Activation\Context.cs:157
Ninject.KernelBase.<Resolve>b__7(IContext context) in c:\Projects\Ninject\Maintenance2.2\ninject\src\Ninject\KernelBase.cs:375
System.Linq.<>c__DisplayClass12
3.b__11(TSource x) +32
System.Linq.WhereSelectEnumerableIterator2.MoveNext() +151
System.Linq.Enumerable.SingleOrDefault(IEnumerable
1 source) +4178557
Ninject.Web.Mvc.NinjectDependencyResolver.GetService(Type serviceType) in c:\Projects\Ninject\Maintenance2.2\ninject.web.mvc\mvc3\src\Ninject.Web.Mvc\NinjectDependencyResolver.cs:56
System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +51

Thanks in advance. I want a working demo of it failing then let me know.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

暗地喜欢 2024-12-18 02:27:45

感谢泰勒·布林克斯发现我的错字!

将命名空间引用更新为

c.IncludeNamespace("TestAopLogging.Models.*");

一切都很好。

希望有人觉得这很有用。

Thanks to Tyler Brinks for spotting my typo!

Update the namespace reference to

c.IncludeNamespace("TestAopLogging.Models.*");

and all is well.

Hope someone finds this useful.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文