首页 > 解决方案 > 方法的 C# 自定义属性,包括使用关键字

问题描述

我需要准备一个Attribute可以作为using声明的自定义。

所以,下面的方法

private async Task<List<TermUserEmailInformationDto>> GetAllTermUserEmailAddressesHedefBelirlemeDirektorVeUstu()
{
    using (_unitOfWorkManager.Current.DisableFilter(GlobalConstants.DataFilters.MustHaveTermId))
    {
        // Code goes on...
    }
}

应该是这样的:

[DisableFilter(GlobalConstants.DataFilters.MustHaveTermId)]
private async Task<List<TermUserEmailInformationDto>> GetAllTermUserEmailAddressesHedefBelirlemeDirektorVeUstu()
{
    // Code goes on...
}

有没有办法做到这一点?

标签: c#attributesusing

解决方案


我建议这样的属性:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
internal class DisableFilterAttribute : Attribute
{
    public DataFilter DataFilter { get; }
    public DisableFilterAttribute(DataFilter dataFilter) => DataFilter = dataFilter;
}

enum DataFilter
{
    MustHaveTermId,
    SomeFilter,
    AnotherFilter
}

注意属性参数的限制。

根据问题中的代码UnitOfWorkManager应该是这样的:

internal class UnitOfWorkManager : IDisposable
{
    public UnitOfWorkManager Current { get; private set; }

    public UnitOfWorkManager()
    {
        Current = this;
    }

    public UnitOfWorkManager DisableFilter(DataFilter dataFilter)
    {
        var manager = new UnitOfWorkManager();
        Console.WriteLine($"Created  UnitOfWorkManager {manger.GetHashCode()} with {dataFilter} disabled");
        return manager;
    }

    public void Dispose() { Console.WriteLine($"Disposed UnitOfWorkManager {GetHashCode()}"); }
}

我建议UnitOfWorkManager用这样的方法修改:

public void DoWithFilters(Action action)
{
    var current = Current;

    var managers = new List<UnitOfWorkManager>();
    foreach (var attribute in
                new StackTrace().GetFrame(1).GetMethod().GetCustomAttributes(false).OfType<DisableFilterAttribute>())
        managers.Add(Current = Current.DisableFilter(attribute.DataFilter));

    action();

    managers.Reverse();
    foreach (var manager in managers)
        manager.Dispose();

    Current = current;
}

可以这样使用它:

[DisableFilter(DataFilter.MustHaveTermId)]
[DisableFilter(DataFilter.SomeFilter)]
private Task<List<TermUserEmailInformationDto>> GetAllTermUserEmailAddressesHedefBelirlemeDirektorVeUstu()
{
    Task<List<TermUserEmailInformationDto>> result = null;
    _unitOfWorkManager.DoWithFilters(() =>
    {
        Console.WriteLine("Performing GetAllTermUserEmailAddressesHedefBelirlemeDirektorVeUstu");
        // Code goes on...
    });
    return result;
}

跑步

Console.WriteLine($"Before method called Current is {_unitOfWorkManager.Current.GetHashCode()}");
GetAllTermUserEmailAddressesHedefBelirlemeDirektorVeUstu();
Console.WriteLine($"After  method called Current is {_unitOfWorkManager.Current.GetHashCode()}");

给出如下结果:

Before method called Current is 46104728
Created  UnitOfWorkManager 21083178 with MustHaveTermId disabled
Created  UnitOfWorkManager 30015890 with SomeFilter disabled
Performing GetAllTermUserEmailAddressesHedefBelirlemeDirektorVeUstu
Disposed UnitOfWorkManager 30015890
Disposed UnitOfWorkManager 21083178
After  method called Current is 46104728

这是上面代码的链接


推荐阅读