Unity - 按名称和条件解决所有问题

发布于 2024-11-06 05:49:21 字数 131 浏览 1 评论 0原文

我想知道是否可以通过对它们注册的名称的某些条件来解决 Unity 中的所有依赖关系。

例如: 解析所有注册名称以“ProcessA”开头的接口。

如果没有办法做到这一点,那么也许我如何扩展 Unity 来允许这样做。

I was wondering if it is possible to resolve all dependancies in Unity by some condition on the name that they were registered.

For example:
Resloving all interfaces registered where the name registered starts with "ProcessA".

And if there is no way to do this then perhaps how can i extend Unity to allow this.

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

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

发布评论

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

评论(2

风吹雨成花 2024-11-13 05:49:21

您应该能够使用 Registrations 来执行此操作,我会推荐一种扩展方法,而不是直接扩展 Unity:

var matches = c.Resolve<IMyService>(name => name.StartsWith("ProcessA"));

使用此扩展方法:

public static class MyUnityExtensions
{
    public static IEnumerable<T> Resolve<T>(this IUnityContainer c, Func<string, bool> match)
    {
        var matches = c.Registrations.Where(r => match(r.Name));

        foreach (var registration in matches)
        {
            yield return c.Resolve<T>(registration.Name);
        }
    }

}

You should be able to use Registrations to do this and I would recommend an extension method rather than extending Unity directly:

var matches = c.Resolve<IMyService>(name => name.StartsWith("ProcessA"));

Using this extension method:

public static class MyUnityExtensions
{
    public static IEnumerable<T> Resolve<T>(this IUnityContainer c, Func<string, bool> match)
    {
        var matches = c.Registrations.Where(r => match(r.Name));

        foreach (var registration in matches)
        {
            yield return c.Resolve<T>(registration.Name);
        }
    }

}
清君侧 2024-11-13 05:49:21

只是添加到迈克尔的答案,我扩展了它,允许您使用相同的名称注册,但使用解析所有来仅解析针对该名称注册的那些。

public struct ScopedName<T>
{
    private const string Separator = "|";

    private readonly string _name;
    private readonly string _registrationName;

    public ScopedName(string name)
        : this()
    {
        _name = name;
        _registrationName = name + Separator + typeof(T).FullName;
    }

    public static implicit operator string(ScopedName<T> scopedName)
    {
        return scopedName._registrationName;
    }

    public bool IsMatach(string other)
    {
        if (string.IsNullOrWhiteSpace(other))
        {
            return false;
        }

        var i = other.IndexOf(Separator, StringComparison.InvariantCulture);
        if (i < 0)
        {
            return false;
        }

        return string.Equals(_name, other.Substring(0, i), StringComparison.InvariantCulture);
    }
}

public static class UnityEx 
{
    public static IUnityContainer RegisterType<TFrom, TTo>(
        this IUnityContainer container,
        ScopedName<TTo> scopedName,
        LifetimeManager lifetimeManager,
        params InjectionMember[] injectionMembers) where TTo : TFrom
    {
        return container.RegisterType(typeof(TFrom), typeof(TTo), scopedName, lifetimeManager, injectionMembers);
    }

    public static IEnumerable<T> ResolveAll<T>(this IUnityContainer container, ScopedName<T> name, params ResolverOverride[] resolverOverrides)
    {
        var matches = container.Registrations.Where(r => name.IsMatach(r.Name));

        foreach (var registration in matches)
        {
            yield return container.Resolve<T>(registration.Name, resolverOverrides);
        }
    }
}

允许像这样的注册和解析:

        container.RegisterType<IFoo, Foo1>(new ScopedName<Foo1>("Scope1"), new HierarchicalLifetimeManager());
        container.RegisterType<IFoo, Foo2>(new ScopedName<Foo2>("Scope1"), new HierarchicalLifetimeManager());

        container.RegisterType<IFoo, Foo3>(new ScopedName<Foo3>("Scope2"), new HierarchicalLifetimeManager());
        container.RegisterType<IFoo, Foo4>(new ScopedName<Foo4>("Scope2"), new HierarchicalLifetimeManager());

        var scope1Foos = container.ResolveAll(new ScopedName<IFoo>("Scope1"));
        var scope2Foos = container.ResolveAll(new ScopedName<IFoo>("Scope2"));

scope1Foos 将包含 Foo1 和 Foo2,scope2Foos 将包含 Foo3 和 Foo4

Just adding to Michael's answer, I extended that to allow you to register with the same names yet use resolve all to only resolve those registered against that name.

public struct ScopedName<T>
{
    private const string Separator = "|";

    private readonly string _name;
    private readonly string _registrationName;

    public ScopedName(string name)
        : this()
    {
        _name = name;
        _registrationName = name + Separator + typeof(T).FullName;
    }

    public static implicit operator string(ScopedName<T> scopedName)
    {
        return scopedName._registrationName;
    }

    public bool IsMatach(string other)
    {
        if (string.IsNullOrWhiteSpace(other))
        {
            return false;
        }

        var i = other.IndexOf(Separator, StringComparison.InvariantCulture);
        if (i < 0)
        {
            return false;
        }

        return string.Equals(_name, other.Substring(0, i), StringComparison.InvariantCulture);
    }
}

public static class UnityEx 
{
    public static IUnityContainer RegisterType<TFrom, TTo>(
        this IUnityContainer container,
        ScopedName<TTo> scopedName,
        LifetimeManager lifetimeManager,
        params InjectionMember[] injectionMembers) where TTo : TFrom
    {
        return container.RegisterType(typeof(TFrom), typeof(TTo), scopedName, lifetimeManager, injectionMembers);
    }

    public static IEnumerable<T> ResolveAll<T>(this IUnityContainer container, ScopedName<T> name, params ResolverOverride[] resolverOverrides)
    {
        var matches = container.Registrations.Where(r => name.IsMatach(r.Name));

        foreach (var registration in matches)
        {
            yield return container.Resolve<T>(registration.Name, resolverOverrides);
        }
    }
}

Allows for registration and resolution like this:

        container.RegisterType<IFoo, Foo1>(new ScopedName<Foo1>("Scope1"), new HierarchicalLifetimeManager());
        container.RegisterType<IFoo, Foo2>(new ScopedName<Foo2>("Scope1"), new HierarchicalLifetimeManager());

        container.RegisterType<IFoo, Foo3>(new ScopedName<Foo3>("Scope2"), new HierarchicalLifetimeManager());
        container.RegisterType<IFoo, Foo4>(new ScopedName<Foo4>("Scope2"), new HierarchicalLifetimeManager());

        var scope1Foos = container.ResolveAll(new ScopedName<IFoo>("Scope1"));
        var scope2Foos = container.ResolveAll(new ScopedName<IFoo>("Scope2"));

scope1Foos will container both Foo1 and Foo2, scope2Foos will contain both Foo3 and Foo4

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