2015-05-09 39 views
1

這是我第一次AutoMapper項目,可能會明顯一些,但教程和例子不是我一下。我想了解如何在某種程度上註冊(我想我需要配置文件)我的地圖以供使用。有很多MVC的例子說要使用全局的asax,這是有道理的,但是在圖書館項目中什麼是等價的?放置位置AutoMapper地圖登記參考DLL

在我的沙箱我有一個winform應用程序和核心庫。 winform應用程序調用庫提供的方法,它是使用automapper的這些庫方法之一。

所以對這裏的一些背景是我的地圖: (要說清楚的映射是相同的核心庫項目)

public class Raw_Full_Map  
{ 
    public Raw_Full_Map() 
    { 

     Mapper.CreateMap<IEnumerable<RawData>, FullData>() 
      .ForMember(d => d.Acres, m => m.ResolveUsing(new RawLeadDataNameResolver("Acres"))); 
     //this is clearly just a snip to show it's a basic map 
    } 
} 

這是被稱爲核心庫的方法:(注意這是一個靜態..這意味着我不會有一個構造函數......如果這是我的問題,那麼我明白,AutoMapper不能被靜態輔助類使用...這是沒有道理的....所以可能我只是沒有做正確

public static class RawDataProcessing 
{ 

    public static FullData HTMLDataScrape(string htmlScrape) 
    { 

     HtmlDocument doc = new HtmlDocument(); 
     doc.LoadHtml(htmlScrape); 

     var list = Recurse(doc.DocumentNode); 
     //HTML agility stuff that turns my html doc into a List<RawData> object 


     return Mapper.Map<FullData>(list); 


    } 

我的測試設備調用我像這樣:

var _data = RawDataProcessing.HTMLDataScrape(rawHTML); 

這當然錯誤,因爲地圖是不是「註冊」。

如果我這樣做的測試工具:

var x = new RawData_FullData(); 

var _data = RawDataProcessing.HTMLDataScrape(rawHTML); 

然後一切正常,我的地​​圖獲取的註冊儘管我認爲一個真正的僞造方式......但它確實工作。

所以,問題是我怎麼註冊我的核心庫項目映射......所以,任何方法可以用它...有沒有真正在DLL中的等價Global.asax的是嗎?

謝謝你幫我接的缺失部分。

回答

2

放入源或映射的目標類型的靜態構造。

public class FullData 
{ 
    static FullData() 
    { 

     Mapper.CreateMap<IEnumerable<RawData>, FullData>() 
      .ForMember(d => d.Acres, m => m.ResolveUsing(new RawLeadDataNameResolver("Acres"))); 
    } 
} 

靜態構造函數將自動被調用的第一次嘗試使用類型FullData任何東西(例如映射)。

+0

AHHHH。我不知道你可以做一個靜態構造函數...只是使用關鍵字靜態...似乎很直接。謝謝!! – GPGVM

1

您可以使用PreApplicationStartMethod任何類,它是在你的類庫方法,它會從你的啓動項目,如果你想自動調用該在啓動時被引用。然後,您可以在該方法中註冊所有映射。順便說一下,我建議使用AddProfile來註冊所有映射。

[assembly: PreApplicationStartMethod(typeof(MyClassLibrary.Startup), "Start")] 
namespace MyClassLibrary 
{ 
    public class Startup 
    { 
     // Automatically will work on startup 
     public static void Start() 
     { 
       Mapper.Initialize(cfg => 
       { 
        Assembly.GetExecutingAssembly().FindAllDerivedTypes<Profile>().ForEach(match => 
        { 
         cfg.AddProfile(Activator.CreateInstance(match) as Profile); 
        }); 
       }); 
     } 
    } 
} 

你只需要建立一個從Profile類派生新類,然後重寫它的Configure()方法:

... 
public class FooMapperProfile:Profile 
{ 
    protected override void Configure() 
    { 
     Mapper.CreateMap<OtherFoo, Foo>() 
       .ForMember(... 
       ... // so on 
    } 
} 

public class AnotherFooMapperProfile:Profile 
{ 
    protected override void Configure() 
    { 
     Mapper.CreateMap<OtherFoo, AnotherFoo>() 
       .ForMember(... 
       ... // so on; 
    } 
} 
... 
// and so on 

其他信息: 如果你看過我都初始化與該代碼的映射:

Mapper.Initialize(cfg => 
{ 
     Assembly.GetExecutingAssembly().FindAllDerivedTypes<Profile>().ForEach(match => 
     { 
       cfg.AddProfile(Activator.CreateInstance(match) as Profile); 
     }); 
}); 

它會自動查找從Profile派生的所有類型,並在創建新實例後添加所有配置文件。

UPDATE1:

由於@Scott Chamberlain評論,PreApplicationStartMethod僅適用於ASP.NET應用程序。這不適用於桌面應用程序。如果您使用Wpf,那麼您可以使用Application.OnStartup方法。或在負載事件中致電Start.Startup();

UPDATE2:
FindAllDerivedTypes擴展方法:

public static class AssemblyExtensions 
    { 
     public static List<Type> FindAllDerivedTypes<T>(this Assembly assembly) 
     { 
      var derivedType = typeof(T); 
      return assembly.GetTypes() 
          .Where(t => t != derivedType && derivedType.IsAssignableFrom(t)) 
          .ToList(); 

     } 
    } 
+0

是的,我知道要使用配置文件,但您提供了有關PreApplicationStartMethod的新信息,以及我在自動映射器配置文件中沒有看到的一些教程,其中包括一次性註冊所有內容的漂亮linq lambda。很酷。謝謝。 – GPGVM

+0

@ user1278561很高興爲您提供幫助。 –

+0

PreApplicationStartMethod是否有多個名稱空間?我在Webactivator和system.web中看到它。我只是將其中的一個添加到我的類庫中以獲得「效果」,即使它不是Web項目? – GPGVM