У меня есть концептуальный / теоретический вопрос о слабой связи и интерфейсах.
Так что одним из способов использования интерфейса может быть инкапсуляция параметров, требуемых определенным конструктором:
class Foo
{
public Foo(IFooInterface foo)
{
// do stuff that depends on the members of IFooInterface
}
}
Поэтому, пока объект, переданный в, реализует договор, все будет работать.Насколько я понимаю, основное преимущество здесь заключается в том, что он обеспечивает полиморфизм, но я не уверен, имеет ли это какое-либо отношение к слабой связи.
Допустим, в качестве аргумента, IFooInterface выглядит следующим образом:
interface IFooInterface
{
string FooString { get; set; }
int FooInt { get; set; }
void DoFoo(string _str);
}
С точки зрения слабой связи, не лучше ли НЕ использовать IFooInterface в вышеприведенном конструкторе, а вместо этого настроить Foo следующим образом:
class Foo
{
public Foo(string _fooString, int _fooInt, Action<string> _doFoo)
{
// do the same operations
}
}
Потому что, скажем,Я хочу добавить функциональность Foo в другой проект.Это означает, что другой проект также должен ссылаться на IFooInterface, добавляя другую зависимость.Но таким образом я могу поместить Foo в другой проект, и он выражает именно то, что ему нужно для работы.Очевидно, я могу просто использовать перегруженные конструкторы, но, скажем так, ради аргумента я не хочу и / или не могу модифицировать конструкторы Foo.
Самый существенный недостаток (по крайней мере для меня) заключается в том, что если у вас есть метод с кучей примитивных параметров, он становится уродливым и трудным для чтения.Поэтому у меня возникла идея создать своего рода функцию обтекания, которая позволит вам передавать интерфейс, а не все примитивные типы:
public static Func<T, R> Wrap<T, R>(Func<T, object[]> conversion)
{
return new Func<T, R>(t =>
{
object[] parameters = conversion(t);
Type[] args = new Type[parameters.Length];
for (int i = 0; i < parameters.Length; i++)
{
args[i] = parameters[i].GetType();
}
ConstructorInfo info = typeof(R).GetConstructor(args);
return (R)info.Invoke(parameters);
});
}
Идея в том, что я могу вернуть функцию, которая принимаетэкземпляр некоторого интерфейса, который соответствует требованиям Foo, но Foo буквально ничего не знает об этом интерфейсе.Его можно использовать так:
public Foo MakeFoo(IFooInterface foo)
{
return Wrap<IFooInterface, Foo>(f =>
new object[] { f.FooString, f.FooInt, f.DoFoo })(foo);
}
Я слышал дискуссию о том, как интерфейсы должны обеспечивать слабую связь, но мне было интересно об этом.
Интересно, что думают некоторые опытные программисты.