Я создаю Фабрику для компонентов моего приложения на основе универсальных интерфейсов.
Я реализовал один метод фабрики для создания компонентов и один метод 'Init' (расширение) для внедрения зависимостей в каждый тип компонента.
Код компилируется и запускается, как и ожидалось. В любом случае Visual Studio (версии 2015 и 2017) не может правильно отображать мои методы 'Init' на объектах компонентов. Под «неудачами» я подразумеваю, что Visual Studio 2015 их вообще не показывает. Visual Studio 2017 ведет себя немного по-другому, поскольку, по крайней мере, он показывает их, но он также показывает неправильные и не может динамически разрешать универсальные типы.
Следующий код является упрощением моего фактического кода, но все же достаточно, чтобы воспроизвести проблему.
Это мои компоненты интерфейсов:
public interface IBaseComponent { }
public interface IComponent : IBaseComponent { }
public interface IComponent<TDependency> : IBaseComponent { }
public interface IComponent<TDependency1, TDependency2> : IBaseComponent { }
Это заводской код:
public static class ComponentFactory
{
//Method to create the component
public static T CreateComponent<T>() where T : IBaseComponent
{
//return instance of T
}
//Extension method to initialize the component
public static T Init<T>(this T component) where T : IComponent
{ //Do stuff and return component.. }
//Extension method to initialize the component and inject depenencies
public static T Init<T, TDependency>(this T component, TDependency dependency) where T : IComponent<TDependency>
{ //Do stuff and return component.. }
//Extension method to initialize the component and inject depenencies
public static T Init<T, TDependency1, TDependency2>(this T component, TDependency1 dependency1, TDependency2 dependency2) where T : IComponent<TDependency1, TDependency2>
{ //Do stuff and return component.. }
}
Эти классы реализуют интерфейсы IComponent:
public class MyComponent : IComponent { }
public class MyComponent1A : IComponent<MyComponent> { }
public class MyComponent1B : IComponent<MyComponent> { }
public class MyComponent2 : IComponent<MyComponent1A, MyComponent1B> { }
И вот как я называю фабричные методы:
MyComponent mC = ComponentFactory.CreateComponent<MyComponent>().Init();
MyComponent1A mC1A = ComponentFactory.CreateComponent<MyComponent1A>().Init(mC);
MyComponent1B mC1B = ComponentFactory.CreateComponent<MyComponent1B>().Init(mC);
MyComponent2 mC2 = ComponentFactory.CreateComponent<MyComponent2>().Init(mC1A, mC1B);
Я ожидаю, что Visual Studio предложит мне правильный метод Init для каждого класса компонентов, например:
MyComponent => Init<MyComponent>(this MyComponent component);
MyComponent1A => Init<MyComponent1A, MyComponent>(this MyComponent1A component, MyComponent dependency);
MyComponent1B => Init<MyComponent1B, MyComponent>(this MyComponent1B component, MyComponent dependency);
MyComponent2 => Init<MyComponent2, MyComponent1A, MyComponent1B>(this MyComponent2 component, MyComponent1A dependency1, MyComponent1B dependency2);
Вместо этого Visual Studio 2015 может показывать только метод Init для MyComponent, но не отображает методы для MyComponent1A, MyComponent1B и MyComponent2
Visual Studio 2017 с любопытством показывает все методы Init для класса MyComponent и только последние два для остальных трех классов. Он также оставляет имена обобщенных типов вместо того, чтобы заменять их правильными для фактического класса.
MyComponent => Init<MyComponent>(this MyComponent component); /*Correct*/
MyComponent => Init<MyComponent, TDependency>(this MyComponent component, TDependency dependency); /*Wrong*/
MyComponent => Init<MyComponent, TDependency1, TDependency2>(this MyComponent component, TDependency1 dependency, TDependency2 dependency); /*Wrong*/
MyComponent1A => Init<MyComponent1A, TDependency>(this MyComponent1A component, TDependency dependency); /*Correct*/
MyComponent1A => Init<MyComponent1A , TDependency1, TDependency2>(this MyComponent1A component, TDependency1 dependency, TDependency2 dependency); /*Wrong*/
//etc..
Очевидно, что из-за ограничений параметров типа, которые я наложил на методы расширения, Wrong те даже не компилируются.
У меня такое ощущение, что на VS2015 я некоторое время видел, как он работает, и я не уверен, что проблема в моем коде или в VS.
Отсутствующее предложение Intellisense почти не соответствует цели моего кода.
Кто-нибудь может заставить его появиться?
Что-то не так с моим кодом, которого я не вижу, или какие-то изменения, которые я мог бы сделать, чтобы избежать этой проблемы?
Спасибо