2010-07-30 2 views
2

У меня есть следующий тестовый класс:Как установить интерфейс в родовом динамическом режиме?

public class OutsideClass 
{ 
    private List<Type> _interfaces = null; 

    public void InjectInterfaces(Type[] types) 
    { 
     if(_interfaces == null) 
     { 
      _interfaces = new List<Type>(); 
     } 

     foreach (var type in types) 
     { 
      if(type.IsInterface) 
      { 
       _interfaces.Add(type); 
      } 
     } 
    } 

    public void PerformSomethingWithTheInterfaces() 
    { 
     foreach (var i in _interfaces) 
     { 
      new Test<i>().PerformSomething(); // On this line the error occurs 
     } 
    } 
} 

internal class Test<T> 
{ 
    internal void PerformSomething() 
    { 

    } 
} 

Это дает мне на однако сообщение Type or namespace name expected. Как я могу настроить этот код так, чтобы он работал?

То, что я пытаюсь сделать, это передать кучу интерфейсов в библиотеку классов, пройти через интерфейсы и использовать Unity, чтобы решить, на основе интерфейса, что-то. Я использую метод расширения Resolve.

+0

Не могли бы вы объяснить, что вы пытаетесь сделать здесь? –

ответ

0

Вы не можете передавать значения в качестве общих аргументов. Только типы. Ставка:

типof (строка)! = Строка.

+0

Чтобы быть понятным, вы называете строку не «System.String», а скорее токеном C#. –

0

Я не думаю, что это может сработать. Вы специализируетесь на родовом статическом имени типа. Вы не можете передать ссылку на объект Type.

Есть способы делать то, что вы хотите, но они связаны с C# 4 и DynamicObject.

+0

Ответ Скита прав, конечно, хотя он использует отражение прямо вместо скрытого отражения «динамического». Я предпочитаю последнее, потому что это позволяет сделать динамику 'PerformSomethingWithTheInterfaces'. –

+0

К сожалению, я все еще на .NET 3.5. Однако для дальнейшего использования у вас есть образец с DynamicObject? –

+0

Вам все равно нужно использовать отражение даже при динамической типизации, чтобы создать экземпляр 'Test '. –

3

Вы должны были бы использовать отражение ... что-то вроде этого:

foreach (Type type in _interfaces) 
{ 
    Type concreteType = typeof(Test<>).MakeGenericType(new Type[] { type }); 
    MethodInfo method = concreteType.GetMethod("PerformSomething", 
     BindingFlags.Instance | BindingFlags.NonPublic); 
    object instance = Activator.CreateInstance(concreteType); 
    method.Invoke(instance, null); 
} 

(Вы, возможно, потребуется внести незначительные изменения - выше не тестируются и даже скомпилировать.)

С C# 4 и динамическая типизация, вы можете сделать это несколько проще:

foreach (Type type in _interfaces) 
{ 
    Type concreteType = typeof(Test<>).MakeGenericType(new Type[] { type }); 
    dynamic d = Activator.CreateInstance(concreteType); 
    d.PerformSomething(); 
} 
+0

Wow, выглядит пугающе, но я дам ему пытаться. Спасибо, что попытался помочь мне в этом. –

+0

Конечно, это (или что-то очень близкое к нему) будет работать. Но мне интересно, что это за намерение со стороны ОП. Я чувствую, что вы просто дали правильный ответ на неправильный вопрос (и я тоже, конечно). –

0

вы можете действительно хотите посмотреть на C# 4 в MEF только как идея, как замена единства я думаю, что это стоит на самом деле хорошо себя и simplif ies механизмы разрешения много, и может дать функциональность, чтобы выполнить задачу, которую вы пытаетесь сделать проще ..

namespace MEF_Interface 
{ 
    // Interface to recognize the concrete implementation as 
    public interface IMessageWriter 
    { 
     void WriteMessage(); 
    } 

} 

namespace MEF_HelloMessageWriter 
{ 
    // Concrete implementation in another assembly 
    [Export(typeof(IMessageWriter))] 
    public class HelloMessageWriter : IMessageWriter 
    { 
     public void WriteMessage() { Console.WriteLine("Hello!"); } 
    } 
} 

namespace MEF_GoodbyeMessageWriter 
{ 
    // Concrete implementation in another assembly 
    [Export(typeof(IMessageWriter))] 
    public class GoodbyeMessageWriter : IMessageWriter 
    { 
     public void WriteMessage() { Console.WriteLine("Goodbye!"); } 
    } 
} 

namespace MEF_Example 
{ 
    class DIContainer 
    { 
     [Import] 
     public IMessageWriter MessageWriter { get; set; } 

     public DIContainer(string directory) 
     { 
      // No more messy XML DI definition, just a catalog that loads 
      // all exports in a specified directory. Filtering is also available. 
      DirectoryCatalog catalog = new DirectoryCatalog(directory); 
      catalog.Refresh(); 
      var container = new CompositionContainer(catalog); 
      container.ComposeParts(this); 
     } 
    } 

    class Program 
    { 

     static void Main(string[] args) 
     { 
      string helloMessageWriterPath = 
       @"C:\shared\Projects\MEF_Example\MEF_HelloMessageWriter\bin\Debug"; 

      string goodbyeMessageWriterPath = 
       @"C:\shared\Projects\MEF_Example\MEF_GoodbyeMessageWriter\bin\Debug"; 

      DIContainer diHelloContainer = new DIContainer(helloMessageWriterPath); 
      diHelloContainer.MessageWriter.WriteMessage(); 

      DIContainer diGoodbyeContainer = new DIContainer(goodbyeMessageWriterPath); 
      diGoodbyeContainer.MessageWriter.WriteMessage(); 

      Console.ReadLine(); 
     } 
    } 
} 
+0

Это интересно, но я не уверен, что это относится к OP. Опять же, я действительно не понимаю ОП, поэтому я очень легко ошибаюсь. –

+0

Вот как я себя чувствовал. Я не уверен, что OP знает, что он хочет делать, поэтому это может помочь. –

+0

@Jimmy: Пожалуйста, прикрепите свои комментарии с помощью «@» и имени пользователя. В противном случае они не получат уведомления (если это не их вопрос или ответ). –

Смежные вопросы