简体   繁体   English

流畅的界面,需要像C#中的全局方法

[英]Fluent Interface, Need something like global methods in C#

Im currently trying to build a Fluent Interface for a ServiceLocator. 我目前正在尝试为ServiceLocator构建一个Fluent接口。 To ensure that each the developer can easily setup 1-to-n mappings 确保每个开发人员都可以轻松设置1对n映射

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 Singleton工作得很好...... For方法的方法签名看起来像这样

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. C#有一些全局方法,所有方法都在System.Object上定义。 But when I create a new generic ExtensionMethod on System.Object, the method will not be visible. 但是当我在System.Object上创建一个新的通用ExtensionMethod时,该方法将不可见。

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

MethodChaining would be the alternative, but this approach looks sexy :D MethodChaining将是替代方案,但这种方法看起来很性感:D

Has anyone an idea? 有人有想法吗?

Well, actually when I create an extension method for Object , it is visible. 好吧,实际上当我为Object创建一个扩展方法时,它是可见的。 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? 我误解了你的问题了吗?

You need to add a using statement for the namespace containing your extension method in order for it to be visible. 您需要为包含扩展方法的命名空间添加using语句,以使其可见。 Adding extension methods to object is rarely a good idea. object添加扩展方法很少是个好主意。

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. 你要求对象的静态扩展方法(Equals和ReferenceEquals是静态方法 ),这是不可能的。 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());
}

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: 通过查看这两个可疑决策,您可以通过定义For接受多个类型参数的重载来消除对全局方法的需求:

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

The For methods would look like this: For方法看起来像这样:

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. 作为参考,.NET Framework的ActionFunc类型支持9种类型的参数。

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 ? 在解决IFoo时,这不会导致歧义吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM