天天看點

mysql + Fluently NHibernate + WebAPI + Autofac

MySQL、Fluently NHibernate、WebAPI、Autofac,對我來說每一個都是麻煩疙瘩,現在它們為了一個共同的項目而湊合到一起了。一路磕磕碰碰,現在貌似有了一點眉目。

作為一個步入老人癡呆帕金森階段的老革命,我當然要馬上将奮鬥過程記錄下來:

1、MySql + Fluently NHibernate

static ISessionFactory sessionFactory;

public static ISession OpenSession(string connString, string[] assemblys)
{
    if (sessionFactory == null)
    {
        sessionFactory = Fluently.Configure()
            .Database(FluentNHibernate.Cfg.Db.MySQLConfiguration.Standard.
                ConnectionString(connString))
            .Mappings(m =>
            {
                foreach (var item in assemblys)
                {
                    m.FluentMappings.AddFromAssembly(Assembly.Load(item));
                }
            }).BuildSessionFactory();

    }

    return sessionFactory.OpenSession();
}

OpenSession((connString: "server=192.168.0.211; user id=root; password=lt1234; database=pnavrds", assemblys: new string[] { "Pnavrds.Data"      

.NET和NHibernate并不天然支援mysql,是以要在項目添加對mysql.data.dll的引用。mysql.data.dll在mysql的安裝目錄裡有。

比如在 C:\Program Files (x86)\MySQL\Connector.NET 6.9\Assemblies\v4.5

2、WebAPI

有關路由問題。

别看api與MVC很像,但是,MVC支援Area,而api并不。

但是開始時我并不知道。輕車熟路地加了個Area,一通路,直接404。

路由如下:

public override void RegisterArea(AreaRegistrationContext context) 
{
    context.MapRoute(
        "Test_default",
        "Test/{controller}/{id}",
        new      

咋辦呢?難道各種控制器濟濟一堂一鍋粥?後來網上查了​​資料​​,添加了一個路由,改為:

public override void RegisterArea(AreaRegistrationContext context) 
{
    context.Routes.MapHttpRoute(
        "Test_defaultAPI",
        "api/Test/{controller}/{id}",
        new { id = RouteParameter.Optional }
    );
    context.MapRoute(
        "Test_default",
        "Test/{controller}/{action}/{id}",
        new { action = "Index", id = UrlParameter.Optional }
    );
}      

注意,這樣處理之後,同一個控制器,就有兩個位址都可以通路。一個有區域,一個沒有區域:

http://localhost/Pnavrds.API/api/Test/Dev3/10
http://localhost/Pnavrds.API/api/Dev3/10      

因為asp.net webapi并不支援區域,不管你這個控制器放在哪個檔案夾、哪個命名空間下,它都頑強地解釋到根目錄下。我們上面做的努力,僅僅是多了一個含有區域名稱的位址而已。

​​參考資料​​

3、Autofac

這個東東是個好東東。我現在都有點離不開它了。不然那麼多執行個體需要構造,然後每個構造函數都N多參數,太麻煩。但是,因為了解不夠,每次用它,好像都要費一些周折,并且很難調試。

這次也不例外。

1)提示System.Web.Http的版本不對。

引用的system.web.http.dll版本為5.2.3.0,但系統說跟5.2.0.0對應不上,編譯時雖然可以通過,但有警告,建議在app.config裡寫些啥啥啥。我找遍了代碼,都看不到哪裡聲明了5.2.0.0。

後來還是根據編譯器的提示,将它給出的代碼,加到web.config裡,編譯警告就沒有了,運作就再無這個錯誤:

<runtime>    
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Net.Http.Formatting" culture="neutral" publicKeyToken="31bf3856ad364e35"
        <bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0"
      </dependentAssembly>
    </assemblyBinding>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Iesi.Collections" culture="neutral" publicKeyToken="aa95f207798dfdb4"
        <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0"
      </dependentAssembly>
    </assemblyBinding>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Autofac" culture="neutral" publicKeyToken="17863af14b0044da"
        <bindingRedirect oldVersion="0.0.0.0-3.5.0.0" newVersion="3.5.0.0"
      </dependentAssembly>
    </assemblyBinding>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Http" culture="neutral" publicKeyToken="31bf3856ad364e35"
        <bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0"
      </dependentAssembly>
    </assemblyBinding>
  </runtime>      

附上編譯資訊:

<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"><dependentAssembly><assemblyIdentity name="System.Net.Http.Formatting" culture="neutral" publicKeyToken="31bf3856ad364e35"<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0"</dependentAssembly></assemblyBinding><assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"><dependentAssembly><assemblyIdentity name="Iesi.Collections" culture="neutral" publicKeyToken="aa95f207798dfdb4"<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0"</dependentAssembly></assemblyBinding><assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"><dependentAssembly><assemblyIdentity name="Autofac" culture="neutral" publicKeyToken="17863af14b0044da"<bindingRedirect oldVersion="0.0.0.0-3.5.0.0" newVersion="3.5.0.0"</dependentAssembly></assemblyBinding>      
public class AutofacConfig
{
    public static void BuildContainer()
    {
        var builder = new ContainerBuilder();

        //Infrastructure objects
        builder.RegisterApiControllers(typeof(WebApiApplication).Assembly);
        builder.RegisterAssemblyTypes(typeof(WebApiApplication).Assembly).AsImplementedInterfaces();

        builder.RegisterModule(new AutofacWebTypesModule());

        //其他代碼.....

        builder.RegisterModelBinderProvider();
        builder.RegisterFilterProvider();

        IContainer container = builder.Build();
        //DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
        GlobalConfiguration.Configuration.DependencyResolver = (new