1

我目前正在尝试为 ServiceLocator 构建流畅的接口。确保每个开发人员都可以轻松设置 1-to-n 映射

我想要这样的东西

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

单例工作正常...... For 方法的方法签名看起来像这样

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

所以我一直在寻找类似全局方法的东西

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

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

MethodChaining 将是替代方案,但这种方法看起来很性感:D

有人有想法吗?

4

3 回答 3

2

好吧,实际上当我为 创建扩展方法时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);        
    }
}

我误解了你的问题吗?

于 2011-09-24T18:18:29.200 回答
1

您需要为using包含您的扩展方法的命名空间添加一条语句,以使其可见。添加扩展方法object很少是一个好主意。

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

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());
}
于 2011-09-24T18:24:41.713 回答
1

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

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

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

这些For方法如下所示:

public void For<TInterface, TImplementation>()

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

...

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

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

于 2011-09-24T18:33:19.190 回答