引擎抽離

      在〈引擎抽離〉中有 1 則留言

為何要抽離引擎

將重要的演算法獨立出來, 並編譯成dll檔, 這叫引擎抽離.  在一個專案中, 將開發出來的重要程式碼, 加以整理並獨立成一個class, 編譯成SDK(類別庫). 這不僅可以賣給別人, 也成為下個專案的引用類別. 這是程式設計師的價值, 具有快速開發的能力. 且因轉成二位進碼, 不需交付原始碼, 保護自己的智慧財產

類別庫專案建立

新增專案, 選擇類別庫 .NET Framework. .專案名請愖重選取. Net Standard具說是建立可以跨平台(Linux, Mac)的SDK, 但經測試, 無法引入其他元件.

引入常用的Window元件

為了使用常用的元件,  如Button, PictureBox等, 先加入/新增項目/選Windows Form, 加入後, 在檔案總管裏就會設定好各項參考, 然後就可以把Form1.cs刪除掉

啟用資源檔

C#可以在SDK綁定資源檔, 這點就比Java方便多了. 在Java中, jar無法引入資源檔, 但Android的aar檔有改進, 也可以綁定資源檔.

請在專案按右鍵/加入/資源檔, 名稱改為Resource.resx

然後於檔案總管的Resource.resx按視下, 點選左方上的影像, 加入資源選取加入現在檔案, 再選取硬碟上的圖片, 即可將圖片置入資源檔內

開始撰寫類別庫

    public class Pokemon:PictureBox
    {
        public Pokemon(int x, int y)
        {
            this.Image = MahalSdk.Resource.pokemon;
            this.SizeMode = PictureBoxSizeMode.StretchImage;
            this.Size = new System.Drawing.Size(100, 100);
            this.Location = new System.Drawing.Point(x, y);
        }
    }

編譯

在方案按建置方案, 或於專案按建置, 即可於 obj\Debug之下出現 dll檔

新專案引用

編譯好的dll如何在新專案中使用呢! 先開啟新專案, 然後於參考中按加入參考/選專案, 再瀏覽剛剛的dll即可

開始撰寫程式碼時, 可直接引用類別庫的類別, 在最上面需打入 using xxxSdk;

XAML套用

若要在XAML套用, 則需加下sdk名稱, 如下

 xmlns:mahalsdk_csharp="clr-namespace:MahalSdk_CSharp;assembly=MahalSdk_CSharp"
 <Grid>
    <mahalsdk_csharp:MahalFile></mahalsdk_csharp:MahalFile>
 </Grid>

 使用者控制項

在自訂的SDK裏, 通常會使用UserControl, 在裏面加入相關組件, 然後包裝成一個自訂的 組件. 底下範例說明如何產生一個檔案目錄結構, 包裝成MahalFile組件, 然後供其他專案使用. 結果 如下圖

file

先在SDK專案中, 新增使用者控制項, 命名為MahalFile. XAML如下

 <Grid>
    <StackPanel>
       <TreeView x:Name="tree" Height="300" Grid.Row="0">
          <TreeView.ItemTemplate>
             <HierarchicalDataTemplate ItemsSource="{Binding children}" >
                <TextBlock Text="{Binding nodeName}"/>
             </HierarchicalDataTemplate>
         </TreeView.ItemTemplate>
         <TreeView.ItemContainerStyle>
            <Style TargetType="{x:Type TreeViewItem}">
               <EventSetter Event="Selected" Handler="itemSelectedChanged"/>
               <EventSetter Event="Expanded" Handler="itemExpanded"/>
            </Style>
         </TreeView.ItemContainerStyle>
       </TreeView>
       <Label x:Name="lblPath" Height="30">
          <Label.Background>
             <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="#FFD9D9D9" Offset="0"/>
                <GradientStop Color="#FFB6B6B6" Offset="1"/>
             </LinearGradientBrush>
          </Label.Background>
       </Label>
    </StackPanel>
 </Grid>

CS代碼如下, 藍色部份為供其他專案產生的事件及可存取的變數

public partial class MahalFile : UserControl
    {
        public event EventHandler SelectedChange;
        List <Node>root { get; set; }
        public MahalFile()
        {
            InitializeComponent();
            DriveInfo[] list = DriveInfo.GetDrives();
            root = new List<Node>();
            foreach (DriveInfo d in list)
            {
                Node node = new Node();
                node.nodeName = d.Name;
                node.nodeFullPath = d.Name;
                getPath(node);
                root.Add(node);
            }
            tree.ItemsSource = root;
        }
        private void getPath(Node item)
        {
            //底下會發生無權限存取Exception
            try
            {
                foreach (DirectoryInfo info in new DirectoryInfo(item.nodeFullPath.ToString()).GetDirectories())
                {
                    Node node = new Node();
                    node.nodeFullPath = item.nodeFullPath.ToString() + info.Name + @"\";
                    node.nodeName = info.Name;
                    item.children.Add(node);
                }
            }
            catch { }
        }
        private void itemSelectedChanged(object sender, RoutedEventArgs e)
        {
            Node node = (Node)tree.SelectedItem;
            node.children.Clear();
            getPath(node);
            foreach (Node sub in node.children)
            {
                getPath(sub);
            }
            lblPath.Content = node.nodeFullPath;
            SelectedChange(node.nodeFullPath, EventArgs.Empty);
        }
        private void itemExpanded(object sender, RoutedEventArgs e)
        {
            TreeViewItem item = e.OriginalSource as TreeViewItem;
            item.IsSelected = true;//觸發item_SelectedChanged
        }
        public string Path {
            get { return lblPath.Content.ToString(); }
        }
        class Node
        {
            public string nodeId { get; set; }
            public string nodeName { get; set; }
            public string nodeContent { get; set; }
            public bool isDelete { get; set; }
            public List<Node> children { get; set; }
            public string nodeFullPath { get; set; }
            public Node()
            {
                this.nodeId = Guid.NewGuid().ToString();
                this.isDelete = false;
                this.children = new List<Node>();
            }

        }
    }

專案應用–XAML

 <Grid> 
    <mahalsdk_csharp:MahalFile x:Name="mahalFile" SelectedChange="mahalFile_SelectedChange">
    </mahalsdk_csharp:MahalFile>
 </Grid>

專案代碼

 private void mahalFile_SelectedChange(object sender, EventArgs e)
 {
     path = (string)sender;
 }

1 thought on “引擎抽離

  1. umalkowskiego

    I am really impressed with your writing skills and also with the layout on your weblog.
    Is this a paid theme or did you customize it yourself?

    Anyway keep up the nice quality writing, it’s rare to
    see a nice blog like this one nowadays.

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *