2011-03-21 3 views
1

구현할 수있는 ISearchable 인터페이스가있는 자체 검색 어셈블리를 만듭니다. 또한 전화 번호에서 검색 할 수있는 기능을 제공하므로 ISearchable을 구현하는 IPhoneNumberSearchable을 갖습니다. 그런 다음 어셈블리를 통해 IPhoneNumberSearchable을 구현하고 검색을 호출하는 항목을 찾습니다. 클래스가 IPhoneNumberSearchable 및 ISearchable을 구현하면 ISearchable 메서드 만 호출합니다. 이 작품을 만드는 방법에 대한 아이디어가 있습니까? 코드 팔로우올바른 메서드를 호출하지 않고 다른 인터페이스를 구현하는 인터페이스를 사용하는 일반 메서드

public class SearchManager 
{ 



    private ISearchItem[] Search<T>(string searchValue) where T: class,ISearchable 
    { 

     Assembly current = System.Reflection.Assembly.GetExecutingAssembly(); 

     IEnumerable<T> instances = from t in Assembly.GetExecutingAssembly().GetTypes() 
         where t.GetInterfaces().Contains(typeof(T)) 
           && t.GetConstructor(Type.EmptyTypes) != null 
         select Activator.CreateInstance(t) as T; 

     var list = new List<ISearchItem>(); 
     foreach (T item in instances) 
     { 
      try 
      { 
       T i = item as T; 
       list.AddRange(item.Search(searchValue)); 
      } 
      catch (System.Exception) { } 
     } 


     return list.ToArray(); 

    } 


    /// <summary> 
    /// Searches the specified search value. 
    /// </summary> 
    /// <param name="searchValue">The search value.</param> 
    /// <returns></returns> 
    public ISearchItem[] Search(string searchValue) 
    { 
     return Search<ISearchable>(searchValue); 
    } 


    /// <summary> 
    /// Searches for phone number. 
    /// </summary> 
    /// <param name="phoneNumber">The phone number.</param> 
    /// <returns></returns> 
    public ISearchItem[] SearchForPhoneNumber(string phoneNumber) 
    { 
     return Search<IPhoneSearchable>(phoneNumber); 
    } 

} 


/// <summary> 
/// 
/// </summary> 
public interface ISearchable 
{ 

    ISearchItem[] Search(string searchValue); 
} 

/// <summary> 
/// 
/// </summary> 
public interface ISearchable 
{ 

    ISearchItem[] Search(string searchValue); 
} 



public class CustomerManager : Search.IPhoneSearchable,Search.ISearchable 
{ 


    /// <summary> 
    /// Searches the specified phone number. 
    /// </summary> 
    /// <param name="phoneNumber">The phone number.</param> 
    /// <returns></returns> 
    Search.ISearchItem[] Search.IPhoneSearchable.Search(string phoneNumber) 
    { 
     //Search based upon phone number    
    } 

    /// <summary> 
    /// Searches the specified search value. 
    /// </summary> 
    /// <param name="searchValue">The search value.</param> 
    /// <returns></returns> 
    Search.ISearchItem[] Search.ISearchable.Search(string searchValue) 
    { 
     //Search on anything code 
    } 
} 
+0

나는 당신의 문제에 대한 해결책을 가지고 있지만, MEF를 살펴 필요가 없습니다 - 당신이 다시 발명하는 것처럼 바퀴 같습니다 http://mef.codeplex.com/ – BrokenGlass

답변

1

이 코드는 언어 사양에 따라 정확하게 작동하므로 예상대로 작동하지 않습니다.

기본적으로 You 클래스 CustomManager ISearchable을 암시 적 및 명시 적으로 구현합니다. 당신이 이것에 대한 그

CustomManager k = new CustomManager(); 
IPhoneSearchable x = k; 
x.Search("strings"); //calls IPhoneSearchable.Search() 
ISearchable y = k; 
y.Search("string"); //calls ISearchable.Search() 
k.Search("string); //calls ISearchable.Search()!!! 

이유처럼 보이는 (반사를 사용하지 않는) 일반 코드에서이 메소드를 호출하려고 할 때 정확하게 코더를 혼동하지. 클래스에 인터페이스를 구현하여이 메서드를 호출 할 때마다이 구현을 호출해야합니다. 다른 이유로 다른 인터페이스를 명시 적으로 구현하는 경우이 정확한 호출을 수행하도록 지정해야합니다.

나는 당신의 디자인에 intefere 싶지 않지만 나에게 이것은 약간 이상해 보인다. 한 가지 방법은 무언가를 검색하고 다른 방법은 특정 내용을 검색하지만 둘 다 약간 다른 기능을 제공하면서 동일한 서명을가집니다. 어쩌면 IPhoneSearchable 실제로 따라서 사용자의 구현 세부 사항을 숨기는 방법 검색을 호출

SearchPhones(string[] filters) 

라는 방법을 제공하는 변경해야합니다. Inteface IPhoneSearchable을 제공함으로써 계약 사양에서 마커 인터페이스를 제공하는 것 외에는 아무 것도하지 않습니다.

그래서 당신은 아마이 컬렉션을 실제 MethodCalls의 컬렉션을 만들 (따라서 CustomManager이 ISearchable에서 검색이 두 메서드 호출을 가지고 있으며, IPhoneSearchable에서 검색)

과 반복 처리해야 귀하의 코드를 수정하고 각 메소드를 호출합니다. 럭키 루크 코드에 의해 설명 된 이유

관련 누가 복음

+0

사실'K를. 검색 ("무언가") 존재하지 않습니다 :) –

+0

미안 AS CII 참으로 암시 적 메서드 구현이 있다고 생각했습니다. 거기에 실제로 아무 k.Search ("무언가") – luckyluke

0

이 작동하지 않습니다. 그러나, 대신

실제 MethodCalls 각 방법

당신이 수를 다음이 컬렉션을 반복하고 전화 (따라서 CustomManager이 ISearchable에서 검색하고 IPhoneSearchable에서 검색이 메서드 호출을 가지고)의 모음 작성 당신의 수색자에서 다음

public interface ISearch 
{ 
    IEnumerable<string> Search(string filter); 
} 

public interface IPhoneSearch : ISearch 
{ 
    new IEnumerable<string> Search(string filter); 
} 

public class Searchable : IPhoneSearch 
{ 
    public IEnumerable<string> Search(string filter) 
    { 
     yield return "Phone!"; 
    } 

    IEnumerable<string> ISearch.Search(string filter) 
    { 
     yield return "Normal!"; 
    } 
} 

그리고 :

(I 약간 코드를 변경) 같은 것을 할

어쨌든 나는이 구현을 변경하는 것이 좋습니다, luckyluke는 말했습니다.

+0

당신의 포인트는 유효한 ASCII입니다, 우리가 모르는 무엇 그는 전화 검색 또는 검색 또는 둘 다 (그러므로 나는 방법 콜 컬렉션을 제안) 전화 만하고 싶어. +1 같은 IsAssignalbleFrom (분명하지만, 약간 differnt 접근 -하지만 그것은 암시 적 변환이 가능할 수도 있습니다 .. – luckyluke

+0

그래, 나는 그들을 개별적으로 부를 수 있기를 원한다. 나는 하나 또는 둘 다를 정의 할 수있는 능력을 원했다. 문제는 제네릭 형식이 IPhoneSearchable인데, 제네릭 형식 (IPhoneSearchable)에서 검색을 호출 할 때 ISearchable 메서드라고 불렀습니다. –

0

내 주된 문제는 제네릭 형식이 IPhoneSearchable인데도 제네릭 형식 (IPhoneSearchable)에서 검색을 호출 할 때 여전히 ISearchable 메서드라고 불렀습니다.

내가 작동하도록 할 수있는 유일한 방법은 리플렉션을 통해 다음 코드를 사용하여 검색을 호출하는 것이 었습니다.

 var list = new List<ISearchItem>(); 
     foreach (T item in instances) 
     { 


      try 
      { 

       var type = typeof(T); 

       var inter = item.GetType().GetInterface(type.Name); 

       var results = (ISearchItem[])inter.InvokeMember("Search", BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public, null, item, new object[] { searchValue }); 
       if(results != null) 
        list.AddRange(results); 
      } 
      catch (System.Exception) { } 
     } 
관련 문제