Flo*_*ers 19 c# entity-framework ninject repository sharp-repository
我真的想将SharpRepository与Ninject一起使用,但我不明白如何配置Ninject以在存储库之间共享Entity Framework DbContext.
我正在使用Entity Framework版本5和Ninject版本3.
目前我Ef5Repository在我的源代码中使用,但我想用它替换它ConfigurationBasedRepository.但我无法弄清楚如何将EF传递(或注入)DbContext到存储库.
示例(当前状态):
using SharpRepository.Repository;
public interface IProductRepository : IRepository<Product>
{
}
using SharpRepository.Ef5Repository;
using System.Data.Entity;
// TODO Tightly coupled to Ef5Repository.
public class ProductRepository : Ef5Repository<Product>, IProductRepository
{
// TODO The DbContext has to be injected manually.
public ProductRepository(DbContext context) : base(context)
{
}
// [...]
}
Run Code Online (Sandbox Code Playgroud)
目标:
using SharpRepository.Repository;
public interface IProductRepository : IRepository<Product>
{
}
public class ProductRepository : ConfigurationBasedRepository<Product, int>, IProductRepository
{
// [...]
}
Run Code Online (Sandbox Code Playgroud)
我已经阅读了两篇博文SharpRepository:Getting Started和SharpRepository:Configuration,但它们都没有帮助我,因为:
所以我的问题:有人能为我提供一些源代码示例如何实现上述目标(DbContext在所有存储库之间共享一个实体框架实例ConfigurationBasedRepository)?
Jef*_*ing 16
首先,您需要安装SharpRepository.Ioc.Ninject NuGet包.这里有扩展方法用于连接Ninject以处理加载通用存储库和设置SharpRepository使用的依赖项解析器.
无论你在哪里设置Ninject绑定规则(对kernel.Bind <>的所有调用),你都需要添加:
kernel.BindSharpRepository();
Run Code Online (Sandbox Code Playgroud)
接下来,在您的Global.asax或App_Start代码或您的Bootstrapper逻辑(无论您何时调用应用程序启动代码)中,您将需要添加以下内容:
// kernel is the specific kernel that you are setting up all the binding for
RepositoryDependencyResolver.SetDependencyResolver(new NinjectDependencyResolver(kernel));
Run Code Online (Sandbox Code Playgroud)
这将告诉SharpRepository在获取新的DbContext时使用此Ninject内核.
最后要做的是为DbContext本身设置绑定规则.如果您在Web应用程序中,则很可能希望DbContext的范围是按请求进行的.我个人不使用Ninject,但我找到了使用InRequestScope的参考资料.我相信你的代码看起来像这样:
kernel.Bind<DbContext>().To<MyCustomEfContext>().InRequestScope().WithConstructorArgument("connectionString", ConfigurationManager.ConnectionStrings["MyCustomEfContext"].ConnectionString);
Run Code Online (Sandbox Code Playgroud)
大多数人不需要这个下一个部分但是如果你的CustomEfContext中有自定义逻辑(我有一个覆盖用于登录对SaveChanges()的调用),那么你需要在配置文件中定义你的自定义上下文类型像这样:
<repositories>
<repository name="ef5Repository" connectionString="CustomEfContext" cachingStrategy="standardCachingStrategy" dbContextType="My.Data.CustomEfContext, My.Data" factory="SharpRepository.Ef5Repository.Ef5ConfigRepositoryFactory, SharpRepository.Ef5Repository" />
</repositories>
Run Code Online (Sandbox Code Playgroud)
其中dbContextType使用完整类型命名空间语法定义您正在使用的自定义DbContext的类型.如果你这样做,那么你需要通过将.Bind <DbContext>()更改为.Bind <CustomEfContext>()来将Ninject设置为自定义上下文.但就像我通常说的那样,你可以直接使用DbContext而不会出现问题.
首先,Jeff T的答案中提供的解决方案是有效的!
我将总结我为使Ninject在ASP.NET MVC 4 + EF 5项目中工作所采取的步骤.值得一提的是,在以下示例中,通过SharpRepository实现了特定存储库模式.
创建一个DbContext派生类,例如Domain.EfContext.它是
"推荐使用上下文的方式".
DbSet<T>公共属性,例如public DbSet<Product> Products { get; set; }在类中声明以下两个构造函数Domain.EfContext:
public EfContext() : base() {}
public EfContext(string connectionName) : base(connectionName) {}
Run Code Online (Sandbox Code Playgroud)
为特定存储库定义接口,例如:
// TODO By extending IRepository, the interface implements default Create-Read-Update-Delete (CRUD) logic.
// We can use "traits" to make the repository more "specific", e.g. via extending "ICanInsert".
// https://github.com/SharpRepository/SharpRepository/blob/master/SharpRepository.Samples/HowToUseTraits.cs
public interface IProjectRepository : IRepository<Project>
{
// TODO Add domain specific logic here.
}
Run Code Online (Sandbox Code Playgroud)定义一个实现特定存储库并继承自的类SharpRepository.Repository.ConfigurationBasedRepository<T, TKey>,例如:
public class ProductRepository : ConfigurationBasedRepository<Product, int>, IProductRepository
{
// TODO Implement domain specific logic here.
}
Run Code Online (Sandbox Code Playgroud)创建一个控制器,例如Controllers.ProductController.
public class ProductController : Controller
{
private IProductRepository Repository { get; private set; }
// TODO Will be used by the DiC.
public ProductController(IProductRepository repository)
{
this.Repository = repository;
}
}
Run Code Online (Sandbox Code Playgroud)该文件App_Start/NinjectWebCommon.cs由Ninject.Web.Common自动创建,我们可以加载我们的模块并RegisterServices(IKernel kernel) : void在类的方法中注册我们的服务NinjectWebCommon.以下是该示例的完整源代码示例:
private static void RegisterServices(IKernel kernel)
{
kernel.BindSharpRepository();
RepositoryDependencyResolver.SetDependencyResolver(
new NinjectDependencyResolver(kernel)
);
string connectionString = ConfigurationManager.ConnectionStrings["EfContext"].ConnectionString;
kernel.Bind<DbContext>()
.To<EfContext>()
.InRequestScope()
.WithConstructorArgument("connectionString", connectionString);
kernel.Bind<IProductRepository>().To<ProductRepository>();
}
Run Code Online (Sandbox Code Playgroud)
在以下sharpRepository部分中定义以下部分Web.config:
<sharpRepository>
<repositories default="ef5Repository">
<repository name="ef5Repository"
connectionString="EfContext"
cachingStrategy="standardCachingStrategy"
dbContextType="Domain.EfContext, Domain"
factory="SharpRepository.Ef5Repository.Ef5ConfigRepositoryFactory, SharpRepository.Ef5Repository"
/>
</repositories>
</sharpRepository>
Run Code Online (Sandbox Code Playgroud)
另外,connectionStrings使示例完成的部分(我正在使用SQL Server LocalDB).
<connectionStrings>
<add name="EfContext" providerName="System.Data.SqlClient" connectionString="Data Source=(localdb)\v11.0;Initial Catalog=Domain;Integrated Security=True" />
</connectionStrings>
Run Code Online (Sandbox Code Playgroud)
我希望这个结论能帮助其他人将ASP.NET MVC 4与Entity Framework 5和SharpRepository一起运行起来!
如果我采取了一个或多个不必要的步骤,或者您看到了改进示例中描述的架构的可能性,请给我回复.
顺便说一句,我不得不将该dbContextType属性添加到该repository部分以使其工作(与Jeff T的答案形成对比).
编辑(2013-08-28):敲定了不必要的步骤(不需要最新版本的SharpRepository).
| 归档时间: |
|
| 查看次数: |
20842 次 |
| 最近记录: |