Feeds:
文章
留言

Archive for 四月 7th, 2008

.NET 和 Flex 在開發上都使用了許多 Attribute,我也一直對 Attribute 的應用很感興趣,可是實務開發應用的不多。主要還是對 .NET Attribute 的掌握度不夠,今天在網路上發現六篇針對 Attribute 的系列文章

*博客园 – dudu – Attribute在.net编程中的应用(一)
*博客园 – dudu – Attribute在.net编程中的应用(二)
*博客园 – dudu – Attribute在.NET编程中的应用(三)
*博客园 – dudu – Attribute在.NET编程中的应用(四)
*博客园 – dudu – Attribute在.NET编程中的应用(五)
*博客园 – dudu – Attribute在.NET编程中的应用(六)

寫的相當不錯,但可惜被埋沒許久。

其中第四篇提到 Attribute + Reflection 製作 SQL Command 產生器的應用,對我前陣子也是寫重複的 SQL Command 帶來不錯的啟發。

我以下嘗試實作 Flex 的 Embed[下載],首先是 Attribute 部份

public enum EmbedImageSource {
    File,
    Http
}

public enum EmbedImageType {
    Jpeg,
    Gif,
    Png
}

[AttributeUsage( AttributeTargets.Field )]
public class EmbedImageAttribute : Attribute {
    private String m_url;
    private EmbedImageSource m_source;
    private EmbedImageType m_type;
    public EmbedImageAttribute(String url, EmbedImageSource source, EmbedImageType type) {
        m_url = url;
        m_source = source;
        m_type = type;
    }

    public String URL {
        get {
            return m_url;
        }
    }

    public EmbedImageType Type {
        get {
            return m_type;
        }
    }

    public EmbedImageSource Source {
        get {
            return m_source;
        }
    }
}

然後是利用 Reflection+ Attribute 產生動載入影像的程式碼,如下:

public class EmbedImageGenerator {
    public static void InitEmbedImage(object obj) {           
        Type t = obj.GetType();           
        FieldInfo[] fis = t.GetFields();
        MemberInfo[] mis = t.GetMembers();
        PropertyInfo[] pis = t.GetProperties();
        foreach (FieldInfo fi in fis) {
            object[] attrs = fi.GetCustomAttributes(false);
            foreach (Attribute attr in attrs) {
                if (attr is EmbedImageAttribute) {
                    EmbedImageAttribute ma = attr as EmbedImageAttribute;
                    if (ma.Source == EmbedImageSource.File) {                                ;
                        fi.SetValue(obj, System.Drawing.Image.FromFile(ma.URL));
                    } else if (ma.Source == EmbedImageSource.Http) {
                        System.Net.WebClient client = new System.Net.WebClient();
                        byte[] bs = client.DownloadData(ma.URL);
                        using (MemoryStream ms = new MemoryStream(bs)) {
                            fi.SetValue(obj, System.Drawing.Image.FromStream(ms));
                        }
                    }
                }
            }
        }           
    }
}

最後是測試程式碼

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Reflection;
using System.Windows.Forms;

namespace ConsoleApplication1 {
    class Program {       
        static void Main(string[] args) {
            Tester t = new Tester();          
        }
    }

    public class Tester {
        [EmbedImage("http://shared.live.com/HjKMzTS-xzcms40!CabizA/emoticons/smile_teeth.gif", EmbedImageSource.Http, EmbedImageType.Gif)]
        public System.Drawing.Image  imgHttp;

        [EmbedImage("d:\logo.jpg", EmbedImageSource.File, EmbedImageType.Jpeg)]
        public System.Drawing.Image imgFile;

        public Tester() {
            //
            EmbedImageGenerator.InitEmbedImage(this);

            Form f = new Form();           
            FlowLayoutPanel flp = new FlowLayoutPanel();
            PictureBox pic = new PictureBox();
            pic.Image = imgFile;
            pic.Size = imgFile.Size;
            flp.Controls.Add(pic);

            pic = new PictureBox();
            pic.Image = imgHttp;
            pic.Size = imgHttp.Size;
            flp.Controls.Add(pic);

            f.Controls.Add(flp);
            f.ShowDialog();
        }
    }
}

以下是上述程式的執行結果

001

雖然依稀可以模擬出 Flex 的 Embed 但是還是很多餘的需要撰寫 EmbedImageGenerator.InitEmbedImage(this); 有點可惜。

另外,如果有用不完的 Attribute,是不是以後寫程式可以像貼標籤一樣簡單就寫完了呢?

Read Full Post »