我正在使用几个需要访问应用程序LINQ DataContext的“主”对象构建DLL。 DLL将为具有不同dataContexts的几个项目提供服务,因此我需要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
答案 0 :(得分:3)
通过将数据上下文传递给需要在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
}
}
答案 1 :(得分: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;
}
}
答案 2 :(得分:1)
目前还不清楚你想做什么,所以我会指出你发布的一些相关答案:
关于结构图,我们的想法是你称之为:
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: public Order(ExeDataContext context):base(context){}