如题

解决方案 »

  1.   

    我的想法是把一个工程分成N个模块,都做成DLL,然后再做一个DATAMODULE的DLL让这N个模块共享
      

  2.   

    注意dll的共享机制和Delphi的包技术的共享机制不同;
    推荐用Delphi的包技术,进行大的功能模块的划分;
    CommonDM:数据连接的共享;肯定整个程序的连接只有一个;如果采用dll共享连接,
    难保一个程序只有一个连接,如果一个程序出现多个连接,那数据库的客户端的数量就会
    减少,可惨了;本来连100个没问题(保持最佳性能),但如果一个程序占用5个(你有五个模块),那数据库只能带20个客户端了;
    CommonDM,共享数据模版的方法,我通过sqlserver的监视器看到只有一个连接;unit CommonDM;interfaceuses
      SysUtils, Classes, DB, ADODB,IniFiles,Dialogs,Forms,
      TCarRentINI;type
      TCommonDataModule = class(TDataModule)
        procedure DataModuleCreate(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
        function GetSystemDateTime():TDateTime;
      end;var
      CommonDataModule: TCommonDataModule;
      CarRentConn: TADOConnection;  UserID:integer;  //用户编号
      DepartmentID : string; //公司部门编号
      RoleID : string; //角色编号
      {
        个人:只能查看自己的信息
        部门:只能查看本部门的信息
        公司:查看全部的公司信息
      }implementation{$R *.dfm}procedure TCommonDataModule.DataModuleCreate(Sender: TObject);
    var
        ConnStr:string;
        ini : CarRentINI;
    begin
        //ini := CarRentINI.Create('E:\易通软件功能文档\源代码\Config\CarRent.ini','cadserver');    ini := CarRentINI.Create(ExtractFileDir(application.exeName)+'\CarRent.ini','cadserver');
        try
            try
                ConnStr := 'Provider='+ini.ReadString('connect','Provider','')+
                           ';Persist Security Info='+ini.ReadString('connect','Persist Security Info','')+
                           ';User ID='+ini.ReadString('connect','User ID','')+
                           ';Password='+ini.ReadString('connect','Password','')+
                           ';Initial Catalog='+ini.ReadString('connect','Initial Catalog','')+
                           ';Data Source='+ini.ReadString('connect','Data Source','');
                if CarRentConn = nil then
                begin
                    CarRentConn := TADOConnection.Create(application);
                    CarRentConn.LoginPrompt:= false;
                    CarRentConn.ConnectionString := ConnStr;
                end;
            finally
                ini.Free;
            end;
        except
             ShowMessage('数据库初始化连接失败');
        end;
    end;function TCommonDataModule.GetSystemDateTime: TDateTime;
    var
        tempQr:TADoQuery;
    begin
        tempQr:=TAdoQuery.Create(nil);
        try
            tempQr.Connection:=CarRentConn;
            tempQr.Close();
            tempQr.SQL.Clear();
            tempQr.SQL.Add('select GetDate()');
            tempQr.Prepared;
            tempQr.Open();
            Result:=tempQr.Fields[0].Value;
        Finally
            tempQr.Free();
        end
    end;initialization
        RegisterClass(TCommonDataModule);finalization
        UnRegisterClass(TCommonDataModule);end.
    ********************************************************************
    其他分功能的模块引用CommonDM,模块内部要建立ADOConnnection的连接实例;
    要在主模块里建立实例;
    ********************************************************************
    在主模块的DM里Create事件里
    unit CarRentDM;interfaceuses
      SysUtils, Classes, DB, ADODB,Forms,CommonDM;type
      TCarRentDataModule = class(TDataModule)
        procedure DataModuleCreate(Sender: TObject);
        procedure DataModuleDestroy(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      CarRentDataModule: TCarRentDataModule;implementation{$R *.dfm}
    var
      //myCommonDM:TCommonDataModule;
      DMpk:HMODULE;
      h:TPersistentClass;procedure TCarRentDataModule.DataModuleCreate(Sender: TObject);
    begin
        //////////////公用数据库连接////////////////////
        DMpk:=LoadPackage('CommonPk.bpl');
        h := GetClass('TCommonDataModule');
        CommonDataModule:=TCommonDataModule(TComponentClass(h).Create(Application));    //发布时考虑删除
        //ADOConnection1 := CarRentConn;
        //AdoConnection1.Open;
    end;procedure TCarRentDataModule.DataModuleDestroy(Sender: TObject);
    begin
        if DMpk<>0 then UnLoadPackage(DMpk);
    end;end.
    ****************************
    CommonDM里的全局变量 CarRentConn 是个模块共享的连接;
      

  3.   

    应该现了解在delphi中dll的使用特性。
    及dll的应用机制。dll适用于开发大型工程时,分成若干个子工程时可以使用。
    如果只是用来编写类似的函数库。然后调用它。
    那么切记不要在该dll中使用vcl组件。
    也就是说一个主程序,一个dll文件。
    主程序不能控制dll文件中的vcl组件,
    dll文件也不能控制主程序中的vcl组件。
    只用将纯业务的程序封装在dll中是可以的
    照上面说的,您最好不要将datamodule封装成dll文件(您肯定会在里面用到数据库组件),然后主程序调用它。您最好写在包或组件里!
      

  4.   

    我是想把工程分模块来做,做N个DLL文件,但是和数据库的连接我又想用DATAMODULE来统一做,而不是在每个模块甚至每个窗体里放数据库组件,因为这样数据库组件其实有很多是重复的,所以我就想到了把一个DATAMODULE做成DLL.
      

  5.   

    我上面不是给你例子了吗
    但是,用的是包技术,很好用的,好好研究一下吧,用Delphi,最好用包来划分大的模块;
    不要围绕着dll转了,他有很多局限性;没有包更适合Delphi的了;我给你的例子,是数据模版上有一个adoconnection,他是全局共享的,当然你也可以在放一些其他的咚咚,或者功能函数等等;我一般这么设计有的程序             app
                  |
         ------------------------------------
         |        |                         |
         |    CommonDM(通用数据模板)        |
         |--------|-------------------------|
         |        |                         |
        模块1   模块2                      模块3   .....在app实例化CommonDM中的全局性的类,这样CommonDM的实例在整个程序中就只有一个应用了(单态);同时app实例化各个模块,而各个模块都用到了CommonDM中的单态类,他已经被app
    先期实例化了;这种结构要求模块的独立性要好(看你设计的水平了,如果设计的不好,出现单元在包中的重复引用是不允许的),这只是基本结构,看对你有没有帮助;个人意见,仅供参考;csdn要是能贴图就好了!!!!!!!!!!!!
      

  6.   

    和小齐同声呐喊,有图的CSDN将会更精彩!
      

  7.   

    还有,我想问一下哪本Delphi的书介绍包的知识比较多一点,我手头上的几本好象都没介绍到这个知识点。
      

  8.   

    delphi5开发人员指南,其中有介绍包的,但还是不多,我市通过摸索,和看了李维的关于包的介绍后,才有启发的;尤其是和接口一齐应用,那效果无以伦比,dll望尘莫及;
    个人观点:
    如果要用delphi,想到了用dll,那就应该放弃它,马上想到package,如果不会的朋友,真的应该学一学,不难的;到http://qixin000.vicp.net/down  (一般在早8:00到22:00开放,如下不了,请等等再试)
    上面有个package.rar的文件,你可一下载,那时李维关于包的文章;
      

  9.   

    to qixin000:
    sorry,我慢了一步,那个package.rar能否给我发一份,本人的E-MAIL:[email protected],谢谢!