2010-01-26 26 views
3

採用不同的方式,減少代碼維護我已經結束了使用反射來創建我的MDI應用新的形式做實驗使用反射關於可能存在的弱點。在業務應用

這樣做的原因「解決方案」是提供一個集中的地方設置新的形式,實施安全檢查和未來可能的需求。

我目前有一個靜態Activator類,它是用MDI父窗體實例化的,每當我需要爲應用程序創建設置新窗體時,我會調用我創建的方法:private static T CreateForm<T>(params args[]) where T: class。此方法使用System.Activator類來實例化給定的類。我有其他的靜態方法,如public static void ShowCustomers(),實際上使用「反射」方法,調用CreateForm<frmCustomers>(),它設置MDI父級等。

對象創建發生try/catch塊中,我顯示一條消息,如果表單無法創建和原因。

我已經解釋至今沒有可能不驗證需要使用反射在業務應用程序中創建MDI的形式,但我想補充我的應用程序使用另一這有。我有一個實現ISupportInitialize接口的組件,當我將它放到表單上時,它會執行安全檢查並在EndInit方法中拋出System.Security.SecurityException。這種例外情況在CreateForm方法中出現,並且向用戶顯示用戶友好的消息。

此外,我正在考慮可能存儲一個MRU(最近使用)的表單創建和哪裏比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 2010-01-26 22:24:31

回答

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; 
} 

這將實現無反射相同的目標,但需要把一些構造函數邏輯。