C# 我的上下文是否与我的存储库过于耦合?
学习实体框架、存储库和IOC,我试图实现的是实现存储库模式,以便更改我的数据源提供者 请参见开源项目中的示例:C# 我的上下文是否与我的存储库过于耦合?,c#,entity-framework,inversion-of-control,unity-container,repository-pattern,C#,Entity Framework,Inversion Of Control,Unity Container,Repository Pattern,学习实体框架、存储库和IOC,我试图实现的是实现存储库模式,以便更改我的数据源提供者 请参见开源项目中的示例: namespace MyApp.Domain.Interfaces { public interface IEFContext : IDisposable { } } EFContext(实现IEFContext) MemberRepository(实现IMemberRepository) 这是我使用Unity的应用程序控制台 控制台应用程序 名称空间MyAp
namespace MyApp.Domain.Interfaces
{
public interface IEFContext : IDisposable
{
}
}
EFContext(实现IEFContext)
MemberRepository(实现IMemberRepository)
这是我使用Unity的应用程序控制台
控制台应用程序
名称空间MyApp.ConsoleApp
{
公共课程
{
静态void Main(字符串[]参数)
{
var container=new UnityContainer();
container.RegisterType();
container.RegisterType();
var repository=container.Resolve();
var user=repository.GetUser(“johnDoe”);
Console.WriteLine(user.Email);
Console.ReadLine();
}
}
}
我的问题如下:
如果我决定添加新上下文,例如:
namespace MyApp.Data.Context
{
public class EFContext2 : DbContext, IEFContext
{
public const string DBConnectionName = @"MyNewDBName";
public EFContext2() : base(DBConnectionName)
{
}
public DbSet<Member> Member { get; set; }
}
}
名称空间MyApp.Data.Context
{
公共类EFContext2:DbContext,IEFContext
{
公共常量字符串DBConnectionName=@“MyNewDBName”;
public EFContext2():base(DBConnectionName)
{
}
公共数据库集成员{get;set;}
}
}
我只需更改依赖项,如下所示:
namespace MyApp.ConsoleApp
{
public class Program
{
static void Main(string[] args)
{
...
container.RegisterType<IEFContext, EFContext2>();
...
}
}
}
名称空间MyApp.ConsoleApp
{
公共课程
{
静态void Main(字符串[]参数)
{
...
container.RegisterType();
...
}
}
}
但在本例中,MemberRepository与第一个上下文松散耦合。因此,如果我必须更改我的上下文,我还必须更改我的存储库
我想听听你对这件事的看法。
问候
but in this example my MemberRepository is loosely-coupled with my first context. So if I have to change my Context I must also change my repository.
是的,但这是一个行的变化:
private readonly EFContext _context;
到
而不是你的构造器:
public MemberRepository(IEFContext context)
{
_context = context;
}
现在,您可以注入实现IEFContext的任何类型的具体上下文
试想一下:您试图用依赖项注入做的是注入依赖项。但是,你是怎么做到的?好吧,你可以通过泛化这些依赖关系来实现。我的意思是,你希望能够使用不同的上下文,然后你使用一个接口IEFContext
,而不是一个具体的上下文。这就是为什么构造函数需要一个接口
但是,这是第一部分,你的代码的问题是当你说
_context = context as EFContext;
您正在向下转换接口并说:此接口是EFContext。你失去了普遍性。知道当你尝试注入一个,比如说,SQLContext时,你将不能,因为尽管它是和IEFContext,但它不是EFContext。这就是为什么您将作为EFContext
部分删除,然后让
_context = context;
至于第二部分,一般来说,期待和接收接口只是第一部分。现在,您需要告诉编译器您需要一个通用上下文IEFContext,但是您还需要告诉他,无论您接收到哪个上下文,您都应该能够,比如说,GetUsers。这就是你的界面发挥作用的地方。您知道在接口中声明属性public成员GetUser{}
,强制并保证无论到达哪个上下文,您都能够获得您的用户
我希望这是一个简单的理解。祝你好运
是的,但这是一个行的变化:
private readonly EFContext _context;
到
而不是你的构造器:
public MemberRepository(IEFContext context)
{
_context = context;
}
现在,您可以注入实现IEFContext的任何类型的具体上下文
试想一下:您试图用依赖项注入做的是注入依赖项。但是,你是怎么做到的?好吧,你可以通过泛化这些依赖关系来实现。我的意思是,你希望能够使用不同的上下文,然后你使用一个接口IEFContext
,而不是一个具体的上下文。这就是为什么构造函数需要一个接口
但是,这是第一部分,你的代码的问题是当你说
_context = context as EFContext;
您正在向下转换接口并说:此接口是EFContext。你失去了普遍性。知道当你尝试注入一个,比如说,SQLContext时,你将不能,因为尽管它是和IEFContext,但它不是EFContext。这就是为什么您将作为EFContext
部分删除,然后让
_context = context;
至于第二部分,一般来说,期待和接收接口只是第一部分。现在,您需要告诉编译器您需要一个通用上下文IEFContext,但是您还需要告诉他,无论您接收到哪个上下文,您都应该能够,比如说,GetUsers。这就是你的界面发挥作用的地方。您知道在接口中声明属性public成员GetUser{}
,强制并保证无论到达哪个上下文,您都能够获得您的用户
我希望这是一个简单的理解。祝你好运。为什么在为IEFContext注册不同的映射时必须更改存储库?您的存储库使用的是接口,而不是EFContext实现,因此,如果EFContext2正确实现了IEFContext,则无需进行任何更改…并且更改后仍保留EFContext?为什么在注册IEFContext的其他映射时必须更改存储库?您的存储库使用的是接口,而不是EFContext实现,因此如果EFContext2正确地实现了IEFContext,那么就不需要进行任何更改…而且更改后您仍然保留EFContext?事实上,我已经尝试过这一点,但在这种情况下,IEFContext没有成员返回的定义,并且在尝试使用getUser方法时出错。我已经更新了我的问题,使之更加明确。谢谢。很抱歉这么愚蠢,但是我必须在我的iFinterface中添加什么才能使它按照你的建议工作呢?非常感谢你的解释。正如Johnny建议在我的IContext作品中添加dbset,但现在我与EF并列。你有没有一个更好的想法
_context = context;