PostSharp在多租户解决方案中

问题描述 投票:1回答:1

我目前正在寻求将PostSharp日志记录(以及可能的其他自定义方面)添加到ASP.NET Core API项目中。我遇到的问题是我们有一个多租户设计,其中租户信息存储在用户声明中,似乎没有一个好方法从PostSharp方面进入当前会话,所以没有似乎是访问适当租户数据库的好方法。

我只是在错误的树上吠叫?我应该看一下不同的AOP框架吗?

c# asp.net-core postsharp
1个回答
1
投票

为了完整起见,这里是我提出的解决方案,它使用PostSharp和AutoFac。

PostSharp方面可以在编译时应用它们的类上创建属性。使用AutoFac的InjectUnsetProperties函数,我们可以将正确范围的成员注入这些类,即使我们在编译时不了解它们。

因此,我们设置了PostSharp方面:

    [PSerializable]
    public class LoggingAspect : OnMethodBoundaryAspect, IInstanceScopedAspect
    {
        [IntroduceMember(Visibility = Visibility.Public, OverrideAction = MemberOverrideAction.Ignore)]
        [CopyCustomAttributes(typeof(ImportMemberAttribute))]
        public IInjectedObject InjectedObject { get; set; }

        [ImportMember("InjectedObject", IsRequired = true)]
        public Property<IInjectedObject> InjectedObjectProperty;

        public override void OnEntry(MethodExecutionArgs args)
        {
            var data = InjectedObjectProperty.Get().MyData;

            Debug.Print($"OnEntry: {args.Method.Name}, Data: {data}\n");
        }

        public object CreateInstance(AdviceArgs adviceArgs)
        {
            return MemberwiseClone();
        }

        public void RuntimeInitializeInstance()
        {
        }
    }

然后在我们的Startup方法中注册我们想要使用方面的服务:

public IServiceProvider ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

    var builder = new ContainerBuilder();
    builder.Populate(services);

    builder.RegisterType<TestService>().As<ITestService>()
        .InstancePerLifetimeScope()
        .OnActivated(e => e.Context.InjectUnsetProperties(e.Instance))
        ;
    builder.RegisterType<InjectedObject>().As<IInjectedObject>()
        .InstancePerLifetimeScope()
        ;

    var container = builder.Build();

    return new AutofacServiceProvider(container);
}

并将方面添加到我们要记录的方法:

public class TestService : ITestService
{
    public TestService()
    {
        Debug.Print("TestService ctor\n");
    }

    private int _myData = 100;

    [LoggingAspect]
    public int GetData()
    {
        return _myData++;
    }
}

当在请求期间创建服务时,会创建一个新的服务器作为该请求的范围,并且它会获得一个新的IInjectedObject,它也会限定在请求范围内,即使我们的源代码中没有出现IInjectedObject属性。

© www.soinside.com 2019 - 2024. All rights reserved.