【问题标题】:Best practice for DLL calling an object in the EXEDLL 在 EXE 中调用对象的最佳实践
【发布时间】:2010-10-14 01:27:22
【问题描述】:

我正在构建一个包含多个“主”对象的 DLL,这些对象需要访问应用程序 LINQ DataContext。 DLL 将为具有不同数据上下文的多个项目提供服务,因此我需要 DLL 可以调用它在 EXE 中的对象。

最好或优雅的方法是什么?

编辑:澄清
我正在尝试做的代码示例:

'DLL
'---
Public MustInherit Class MasterObject(Of T As Class)
   Friend db As DataContext
   Public Sub New()
      'How do I do something like this?
      db = New DataContextInTheExe()
   End Sub

   ...

   Public MustOverride Sub Save()
end class

'In the Exe
'---
Public Class Order
   Inherits MasterObject(Of Order)

   Public Overrides Sub Save()
       ...
       Me.db.SubmitChanges()
   End Sub
end class

【问题讨论】:

    标签: .net vb.net


    【解决方案1】:

    通过将数据上下文传递给需要在 DLL 中使用它的类来使用依赖注入,通常是通过其构造函数。

    这是一个 C# 示例:

    public abstract class MasterObject<T>
    {
       private DataContext _dataContext;
    
       public MasterObject(DataContext dataContext)
       {
          _dataContext = dataContext;
       }
    }
    
    public class Order : MasterObject<Order>
    {
       public Order(DataContext dataContext) : base(dataContext)
       {
          // additional constructor logic
       }
    }
    

    【讨论】:

    • 你能举个例子吗?
    • 虽然答案完全正确,但我还是选择了Marc的答案,因为它更完整。谢谢!
    【解决方案2】:

    最合适的方法是让 exe 将数据上下文传递给 dll,例如作为 dll 正在执行的任何操作的方法参数,或作为任何类(在 dll 中)的构造函数参数需要它。如果您有不同类型的数据上下文,则类型必须是 DataContext 或子类。扩展方法(在 DataContext 上)是执行此操作的一种方式(但不是唯一方式)。

    或者 - 在标准的“存储库”实现中(其中 dll 是存储库),调用者(exe)完全有可能甚至不知道数据上下文 - 只是 ICustomerRepository 接口(或其他)dll 公开的内容。


    重新编辑;仅凭这一点,它就无法知道要创建的数据上下文的类型。您可能需要或者传入一个数据上下文,或者告诉它(通过泛型)数据上下文的类型;请原谅我的 C#,但是:

    public abstract class MasterObject<TDataContext, TEntity>
        where TDataContext : DataContext, new()
        where TEntity : class
    {
        internal TDataContext db;
        public MasterObject() {
            db = new TDataContext();
        }
    }
    

    但是,我强烈怀疑依赖注入路线更简单 - 即让调用者告诉我们:

    public abstract class MasterObject<TEntity>
        where TEntity : class
    {
        internal DataContext db;
        public MasterObject(DataContext db) {
            this.db = db;
        }
    }
    

    【讨论】:

    • 你会如何使用扩展方法呢?
    • 你的意思是在exe中有扩展方法吗? DLL 如何知道扩展?
    • 不,扩展方法将在 dll 中。扩展方法只是将实例传递给实用程序(共享/静态)方法的一种奇特方式。
    • 好吧,这不是我想要做的。我添加了一个代码示例,希望对您有所帮助。
    【解决方案3】:

    目前还不清楚你想做什么,所以我将向你指出我发布的一些相关答案:

    关于结构图,你可以这样称呼它:

    var someMaster = StructureMap.GetInstance<SomeMasterDefinedInDll>();
    

    Structure Map 将实例化并将所需的任何内容传递给 SomeMasterDefinedInDll 构造函数。您确实需要配置它,因此您告诉它在请求 DataContext 时获取 exe 中定义的上下文。现在,通常 SomeMasterDefinedInDll 是其他东西的依赖项,因此您甚至不需要在上面编写该代码(它是其他东西的构造函数的参数),您只需为层次结构的顶部执行此操作。检查链接,那里解释得很清楚。

    更新:在 c# 语法中,你会:

    public abstract class MasterObject<T>
    {
        protected MasterObject(DataContext context)
        {
        }
    }
    public class Order : MasterObject<Order>
    {
        public Order() : base(new ExeDataContext()) {}
    }
    

    基本上,接收datacontext作为构造函数参数,并在子类中将datacontext传递给基构造函数。

    更新 2: 请注意,上面的代码是对您最初想要做的事情的回复。如果您只是想这样做,那将可以正常工作(不需要其他东西)。也就是说,我建议您研究依赖注入。在这种情况下,也会在 Order 构造函数中收到 ExeDataContext: 公共秩序(ExeDataContext 上下文):基础(上下文){}

    【讨论】:

    • 我添加了一个示例代码,希望它更清楚我想要做什么
    • @Eduardo 更新了如何 - 虽然在 c# 中添加了语法,但带有注释以清除它...
    • @Freddy:您的示例代码没有使用依赖注入,因为依赖仍然是在 dll 中创建的,而不是从 exe 注入的。
    • @Jaime 你是绝对正确的,该代码是为了回复 Eduardo 关于他正在尝试做的事情的更新。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-21
    • 2013-09-23
    • 1970-01-01
    • 2011-07-12
    • 2011-12-27
    • 2021-01-18
    • 2014-01-28
    相关资源
    最近更新 更多