0

有MSDN上Deferring the Resolution of Objects團結推遲對象的分辨率

// Create a Unity container 
IUnityContainer myContainer = new UnityContainer(); 

// Create an IEnumerable resolver for the IMyClass interface type 
var resolver = myContainer.Resolve<Func<IEnumerable<IMyClass>>>(); 

// ... other code here... 

// Register mappings for the IMyClass interface to appropriate concrete types 
myContainer.RegisterType<IMyClass, FirstClass>("First"); 
myContainer.RegisterType<IMyClass, SecondClass>("Second"); 
myContainer.RegisterType<IMyClass, ThidClass>("Third"); 

// Resolve a collection of the mapped target objects 
IEnumerable<IMyClass> myClassInstances = resolver(); 

我鼓舞了一下,試圖完成類似下面的例子。

我的接口和具體類是:

public interface IImplementMe 
{ 
    void DoSomething(); 
} 
public class FirstImplementation : IImplementMe 
{ 
    public void DoSomething() 
    { 
     Console.WriteLine("First"); 
    } 
} 
public class SecondImplementation : IImplementMe 
{ 
    public void DoSomething() 
    { 
     Console.WriteLine("Second"); 
    } 
} 

我的服務類是這樣的:

public class Service 
    { 
     private bool someCondition; 

     Func<Dictionary<string, IImplementMe>> myClassInstances; 
     public Service(Func<Dictionary<string, IImplementMe>> myClassInstances) 
     { 
      this.myClassInstances = myClassInstances; 
     } 


     public void Foo() 
     { 
      if (someCondition) 
      { 
       myClassInstances.Invoke()["First"].DoSomething(); 
      } 
      else 
      { 
       myClassInstances.Invoke()["Second"].DoSomething(); 
      } 
     } 
    } 

正如你能理解,我想註冊一個接口的多個實例,並應使用在需求運行時適當的一個。

我該如何註冊我的類型,以便我可以通過給別名在我的服務類中使用它們。

我知道我可以通過使用別名註冊他們並通過給別名解決它們。但我不想在服務類中提及Unity。

或者也許有更明智的方法來做到這一點。

回答

1

該文檔適用於Unity2。如果您使用Unity3.x,則應使用Lazy<T>而不是Func<T>,如here所述。我會質疑爲什麼你需要使用延期解決方案,因爲構建對象的性能應該幾乎可以忽略不計(如果不是這樣,那麼在構造函數中完成太多工作的代碼味道)。

沒有參考Unity,您的Foo已解決的實例將不知道收集項目的註冊名稱。但是你可以用其他方式區分集合的項目。您可以在IImplementMe上創建一個字符串Name屬性。或者你可以得到解決項目的類型。

+0

你是對的,我沒有使用延期的決議。我的應用程序在.Net 4.0上,所以我必須使用Unity2。其實我試圖註冊一個接口的多個實例。在Unity3中,您可以使用「container.RegisterTypes」來完成此操作,但此擴展方法在Unity2中不存在。 – fkucuk

0

最後,我可以弄清楚一些事情。

謝謝,泰勒..

public enum MyType 
    { 
     First, 
     Second 
    } 

    public interface IImplementMe 
    { 
     MyType TypeOfClass { get; } 
     void DoSomething(); 
    } 
    public class FirstImplementation : IImplementMe 
    { 
     public void DoSomething() 
     { 
      Console.WriteLine("First"); 
     } 

     public MyType TypeOfClass 
     { 
      get 
      { 
       return MyType.First; 
      } 
     } 
    } 
    public class SecondImplementation : IImplementMe 
    { 
     public void DoSomething() 
     { 
      Console.WriteLine("Second"); 
     } 

     public MyType TypeOfClass 
     { 
      get 
      { 
       return MyType.Second; 
      } 
     } 
    } 


    public interface IService { } 
    public class Service : IService 
    { 
     private bool someCondition = true; 

     private IImplementMe first; 
     private IImplementMe second; 
     IEnumerable<IImplementMe> hebele; 

     public Service(IEnumerable<IImplementMe> hebele) 
     { 
      this.hebele = hebele; 
      foreach (var item in hebele) 
      { 
       switch (item.TypeOfClass) 
       { 
        case MyType.First: 
         first = item; 
         break; 
        case MyType.Second: 
         second = item; 
         break; 
        default: 
         break; 
       } 
      } 
     } 


     public void Foo() 
     { 
      if (someCondition) 
      { 
       first.DoSomething(); 
      } 
      else 
      { 
       second.DoSomething(); 
      } 
     } 
    } 




class Program 
    { 
     static void Main(string[] args) 
     { 
      IUnityContainer myContainer = new UnityContainer(); 


      myContainer.RegisterType<IImplementMe, FirstImplementation>("First"); 
      myContainer.RegisterType<IImplementMe, SecondImplementation>("Second"); 
      myContainer.RegisterType<IEnumerable<IImplementMe>, IImplementMe[]>(); 


      myContainer.RegisterType<IService, Service>(); 


      var srv = myContainer.Resolve<Service>(); 
      srv.Foo(); 
     } 
    }