2015-05-24 49 views
0

我們在Windows Forms中開發了一個ERP系統,用戶需要在整個系統中擁有精細的權限。爲了達到這個目的,每個表單幾乎都是它自己的exe。我們有一個主菜單,我們將MenuItem添加到數據庫,然後我們可以授予用戶訪問權限。然後,我們將通過一個Guid通過每個exe作爲「會話」的ID。在exe啓動之前檢查權限,而不是由exe本身檢查。Windows窗體中的權限

所以我們的「主菜單」建成這些exe文件的表是「ID,標題的EXE,..,..)。

所以多年來計劃的發展,我們現在有一個解決方案,其中包含800多個小型項目和4個共享dll(數據,BL,UI,打印)我們的VS解決方案真的與性能相抗衡

我正在考慮將表單組合成幾個項目,使用反射來建立菜單,我想這樣做,而不是啓動一個exe文件,我們將使用反射來實例化窗體並顯示它?這是否是最好的方法來解決這個問題?或者是有一些爲Windows窗體設計的框架可以處理這個嗎?

這也會提高VS性能?相同數量的代碼只是少了一些項目?

除此之外,我們還有用於啓用/禁用控件的應用內權限。雖然我不認爲他們會受此影響。

回答

0

我不確定你的中間步驟,但我最近在erp系統中使用的方法是使用命令模式的變體。如果您將命令放入命令邏輯來檢查安全性並啓動表單或其變體,那麼您可以使用反射來查找命令或在啓動時將它們全部找到並將它們存儲在列表中。無論哪種方式,它都相對簡單。

public interface ICommand 
{ 
    Guid GetUniqueId(); 
    bool Execute(); 
} 

然後實際的命令是這樣的

public class YourWinformCommand: ICommand 
    { 
     private User _user; 
     private Guid _securityCode = new Guid("......."); 

     public Guid GetUniqueId() 
     { 
      return _securityCode; 
     } 

     public bool Execute() 
     { 

      if (_user.HasAccessTo(_securityCode)) 
      { 
       //Load the winform here. 

       return true 
      } 

      return false; 
     } 
    } 

隨着各入口點,你應該能夠到的WinForms合併到邏輯組並將其放置在DLL文件,而不是一個命令。現在,一旦這樣做了使用反射找到它的接口和測試一個給定的命令標識符

/// <summary> 
    /// This class contains methods to construct a concrete object from an interface. 
    /// </summary> 
    public static class ServiceFactory 
    { 


     /// <summary> 
     /// Builds a concrete instance of an interface 
     /// </summary> 
     /// <typeparam name="T">The interface of the object</typeparam> 
     /// <returns>If found, a concrete object is returned that implements the interface</returns> 
     public static T Build<T>() where T : class 
     { 
      string applicationPath = AppDomain.CurrentDomain.BaseDirectory; 

      string[] files = Directory.GetFiles(applicationPath, "*.dll"); 

      foreach (string file in files) 
      { 
       // Dynamically load the selected assembly. 
       Assembly theAssembly = Assembly.LoadFrom(file); 

       // See if the type implements T. 
       foreach (Type type in theAssembly.GetTypes()) 
       { 
        if (ImplementsInterface(type, typeof(T))) 
        { 
         // Use late binding to create the type. 
         return (T) theAssembly.CreateInstance(type.FullName); 
        } 
       } 
      } 
      return null; 
     } 

     public static bool ImplementsInterface(this Type type, Type ifaceType) 
     { 
      return type.GetInterfaces().Any(x => x == ifaceType); 
     } 

} 

從代碼修改,包括公式中的GUID或修改它返回所有的命令,你的選擇。

希望它有幫助。