2010-01-26 2 views
3

다른 접근법을 사용한 실험 및 코드 유지 관리 감소 리플렉션을 사용하여 MDI 응용 프로그램에서 새 양식을 만들었습니다.비즈니스 응용 프로그램에서 리플렉션 사용과 관련된 약점

이 '솔루션'의 이유는 새로운 양식을 설치하고 보안 검사 및 가능한 미래의 요구 사항을 구현하기위한 중심적인 장소를 제공하기위한 것입니다.

현재 MDI 상위 폼으로 인스턴스화 된 정적 Activator 클래스가 있으며 응용 프로그램에 대한 설정 새 폼을 만들 때마다 내가 만든 메서드는 private static T CreateForm<T>(params args[]) where T: class입니다. 이 메서드는 System.Activator 클래스를 사용하여 지정된 클래스를 인스턴스화합니다. 나는 public static void ShowCustomers()과 같은 다른 정적 메서드를 가지고 있는데, 실제로는 MDI 부모를 설정하는 CreateForm<frmCustomers>()을 호출하여 '반사'메서드를 사용합니다.

개체 생성은 try/catch 블록 내에서 발생하며 양식을 만들 수없는 경우 그 이유와 이유를 표시합니다.

지금까지 설명한 내용은 리플렉션을 사용하여 비즈니스 응용 프로그램에서 MDI 양식을 만들 필요가 있는지 여부를 확인하지는 못했지만 내 응용 프로그램에 다른 용도를 추가하고자합니다. ISupportInitialize 인터페이스를 구현하는 구성 요소가 있고이를 폼에 놓으면 보안 검사를 수행하고 EndInit 메서드에서 System.Security.SecurityException을 throw합니다. 이 예외는 CreateForm 메서드에서 발생하며 사용자에게 친숙한 메시지가 사용자에게 표시됩니다.

또한 MRT (가장 최근에 사용한) 목록을 생성하는 방식을 생각하고 있었는데 CreateForm 방법보다이 방법을 사용하는 것이 좋습니다.

나는 코드 냄새, 디자인 냄새 또는 같은 용어에 익숙하지 않아요하지만 난 자주 사용되는 단어를 본 적이 있지만 내 질문은 기본적으로 다음과 같이 요약 될 :

내가 제공 한 정보를 제공 (잘만되면 이해할 수있는),이 접근법은 '나쁘다'는 냄새가 난다.

그렇다면 어떤 접근 방식이 더 적합합니까?

모든 의견을 환영합니다.

감사합니다, 스테판

public class Activator 
{ 
    private static Activator instance; 

    private MainForm mainForm; 

    private Activator(MainForm mainForm) 
    { 
     this.mainForm = mainForm; 
    } 

    private Activator() 
    { 

    }   

    private static Activator Instance 
    { 
     get 
     { 
      if (instance == null) throw new Exception("Not activated"); 
      else return instance; 
     } 
    } 

    private static void ShowMDIChild<T>(params object[] args) where T : class 
    { 
     try 
     { 
      System.Windows.Forms.Form frm = Create<T>(args) as System.Windows.Forms.Form; 
      ShowMDIChild(frm); 
     } 
     catch (Exception e) 
     { 
      // Check if the inner exception is a security exception 
      bool isSecurity = false; 
      if (e.GetType().Equals(typeof(System.Security.SecurityException))) isSecurity = true; 

      if (!isSecurity && e.InnerException != null && e.InnerException.GetType().Equals(typeof(System.Security.SecurityException))) isSecurity = true; 

      if(isSecurity) 
       MessageBox.Show(Instance.mainForm, "You do not have the neccessary privileges to access this resource", "Access denied", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Stop); 
      else 
       MessageBox.Show(Instance.mainForm, e.Message, "An error has occurred", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error); 
     } 
    } 

    private static void ShowMDIChild(System.Windows.Forms.Form form) 
    { 
     Instance.mainForm.ShowMDIChild(form); 
    } 

    private static T Create<T>(params object[] args) where T: class 
    { 
     T result = System.Activator.CreateInstance(typeof(T), args) as T; 

     return result; 
    } 

    public static void Register(MainForm mainForm) 
    { 
     instance = new Activator(mainForm); 
    } 

    public static void Customers() 
    { 
     ShowMDIChild<Forms.Customers>(); 
    } 
} 
+0

이러한 형식은 생성자에서 어떤 형식의 매개 변수를 사용합니까? – ChaosPandion

답변

3

프레임 워크를 직접 만들었습니다. 그것은 당신의 문제를 해결하고, 말했듯이, 코드 유지 보수를 줄여줍니다. 코드에 익숙하다면 다 끝났을 것입니다.

이 프로젝트를 위해 더 많은 개발자를 고용/고용하는 경우에 대비하여 좋은 아이디어는 문서화하는 것이 좋습니다.

0

당신이 이런 일을 할 수있는 생성자에 대한 매개 변수가없는 경우. 그렇지 않은 경우 성능 문제가 발생하지 않는 한 디자인에 아무런 문제가 없습니다 (의심).

public static TForm CreateForm<TForm>() where TForm : Form, new() 
{ 
    return ProccessNewForm<TForm>(new TForm()); 
} 

public static TForm CreateForm<TForm>(Func<TForm, TForm> initializer) where TForm : Form, new() 
{ 
    return ProccessNewForm<TForm>(initializer(new TForm())); 
} 

private static TForm ProccessNewForm<TForm>(TForm newForm) where TForm : Form, new() 
{ 
    // do stuff 

    return newForm; 
} 
1

당신은 IConstruct 같은 인터페이스 구현에 생성자 논리의 모든 이동 같은 것을 허용하는의 CreateForm에 또 다른 제약 조건을 추가 할 수 있습니다

private static T CreateForm<T>(params object[] args) where T : class, new() { 
    T t = new T(); 
    var construct = t as IConstruct; 
    if (construct != null) { 
     construct.Construct(args); 
    } 
    var initialize = t as IInitialize; 
    if (initialize != null) { 
     initialize.Initialize(); 
    } 
    return t; 
} 

이 반사없이 같은 목표를 달성하는 것입니다,하지만 약간의 이동이 필요합니다 생성자 논리.

관련 문제