流畅的接口,需要类似 C# 中的全局方法之类的东西

发布于 2024-12-06 11:06:18 字数 687 浏览 0 评论 0原文

我目前正在尝试为 ServiceLocator 构建流畅的界面。为了确保每个开发人员都可以轻松设置 1 对 n 映射,

我希望像这样的

ServiceLocator.Instance.For<IFoo>(Use<Foo>(), Use<FooBar>());

Singleton 工作正常... For 方法的 methodsignature 看起来像这样

public void For<TInterface>(params type[] services)
{
// ... 
}

所以我正在寻找类似 global 的东西方法

C# 有一些全局方法,所有方法都定义在 System.Object 上。但是,当我在 System.Object 上创建新的通用 ExtensionMethod 时,该方法将不可见。

public static class MyExtensions
{
  public static void Use<T>(this Object instance)
  {
    // ..
  }
}

MethodChaining 是另一种选择,但这种方法看起来很性感:D

有人有想法吗?

Im currently trying to build a Fluent Interface for a ServiceLocator. To ensure that each the developer can easily setup 1-to-n mappings

I'd like something like this

ServiceLocator.Instance.For<IFoo>(Use<Foo>(), Use<FooBar>());

Singleton is workin fine... the methodsignature for the For method looks like this

public void For<TInterface>(params type[] services)
{
// ... 
}

So I was looking for something like a global method

C# has some global methods, all methods which are defined on System.Object. But when I create a new generic ExtensionMethod on System.Object, the method will not be visible.

public static class MyExtensions
{
  public static void Use<T>(this Object instance)
  {
    // ..
  }
}

MethodChaining would be the alternative, but this approach looks sexy :D

Has anyone an idea?

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

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

发布评论

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

评论(3

街角迷惘 2024-12-13 11:06:18

好吧,实际上当我为 Object 创建扩展方法时,它是可见的。比如,

public static class Extensions
{
    public static void doStuff<T>(this T myObject)
    {
    }
}

class Program
{
    static void Main(string[] args)
    {
        int a = 5;
        a.doStuff();

        string b = "aaa";
        b.doStuff();

        List<int> c = new List<int>() { 1, 2, 3, 10 };
        c.doStuff();

        Extensions.doStuff(c);        
    }
}

我误解了你的问题吗?

Well, actually when I create an extension method for Object, it is visible. As in,

public static class Extensions
{
    public static void doStuff<T>(this T myObject)
    {
    }
}

class Program
{
    static void Main(string[] args)
    {
        int a = 5;
        a.doStuff();

        string b = "aaa";
        b.doStuff();

        List<int> c = new List<int>() { 1, 2, 3, 10 };
        c.doStuff();

        Extensions.doStuff(c);        
    }
}

Did I misunderstand your question?

终止放荡 2024-12-13 11:06:18

您需要为包含扩展方法的命名空间添加 using 语句才能使其可见。向对象添加扩展方法并不是一个好主意。

编辑:
好吧,现在我明白你在问什么了。为了使用扩展方法,您需要一个实例。您要求对象上的静态扩展方法(Equals 和 ReferenceEquals 是 static方法),这是不可能的。如果您在对象上定义扩展方法,它将在所有实例上可用,我确信这不是您想要的。

public static class ObjectExtensions
{
    public static string TypeFullName(this object obj)
    {
        return obj.GetType().FullName;
    }
}

static void Main(string[] args)
{
    var obj = new object();
    Console.WriteLine(obj.TypeFullName());

    var s = "test";
    Console.WriteLine(s.TypeFullName());
}

You need to add a using statement for the namespace containing your extension method in order for it to be visible. Adding extension methods to object is rarely a good idea.

EDIT:
Okay, now I understand what you're asking. In order to use an extension method you need an instance. You're asking for a static extension method on object (Equals and ReferenceEquals are static methods), and that's not possible. If you define an extension method on object, it will be available on all instances and I'm sure that's not what you want.

public static class ObjectExtensions
{
    public static string TypeFullName(this object obj)
    {
        return obj.GetType().FullName;
    }
}

static void Main(string[] args)
{
    var obj = new object();
    Console.WriteLine(obj.TypeFullName());

    var s = "test";
    Console.WriteLine(s.TypeFullName());
}
眼前雾蒙蒙 2024-12-13 11:06:18

服务定位器被广泛认为是一种反模式。此外,通用注册接口被广泛认为是一个无法解决的问题,除非您需要使用特定的容器。

回顾这两个有问题的决定,您可以通过定义接受多个类型参数的 For 重载来消除对全局方法的需求:

ServiceLocator.Instance.For<IFoo, Foo, FooBar>();

For 方法如下所示:

public void For<TInterface, TImplementation>()

public void For<TInterface, TImplementation1, TImplementation2>()

...

必须为每个类型计数定义一个重载,但它需要最少的语法和最大的可发现性。作为参考,.NET Framework 的 ActionFunc 类型支持 9 个类型参数。

不过,写完之后,我想知道我是否误解了这个问题:为什么要为同一个接口指定多个实现?这不会导致解析 IFoo 时出现歧义吗?

Service Locator is widely considered to be an anti-pattern. Also, a common registration interface is widely considered to be an unsolvable problem unless you are requiring use of a specific container.

Looking past these two questionable decisions, you can remove the need for the global method by defining overloads of For which accept multiple type arguments:

ServiceLocator.Instance.For<IFoo, Foo, FooBar>();

The For methods would look like this:

public void For<TInterface, TImplementation>()

public void For<TInterface, TImplementation1, TImplementation2>()

...

You have to define an overload for each type count, but it requires the minimal syntax and maximum amount of discoverability. For reference, the .NET Framework's Action and Func types support 9 type arguments.

After writing this out, though, I wonder if I misunderstood the question: why would you specify multiple implementations for the same interface? Wouldn't that lead to ambiguity when resolving IFoo?

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