Chúng tôi đang cố gắng sử dụng Ninject trong một đường ống Owin với WebAPI. Chúng tôi có mọi thứ được thiết lập theo số this documentation, nhưng chúng tôi không thể nhận được InRequestScope() để hoạt động.Sử dụng Ninject với Owin và InRequestScope
Đây là một phần quan trọng của startup.cs
public class Startup
{
public void Configuration(IAppBuilder app)
{
HttpConfiguration config = new HttpConfiguration();
// Web API routes
config.MapHttpAttributeRoutes();
// Ninject Setup
app.UseNinjectMiddleware(NinjectConfig.CreateKernel);
app.UseNinjectWebApi(config);
}
}
NinjectConfig trông giống như sau:
public sealed class NinjectConfig
{
public static IKernel CreateKernel()
{
var kernel = new StandardKernel();
INinjectModule[] modules =
{
new ApplicationModule()
};
instance.Load(modules);
// Do we still need to do this wtih Owin?
instance.Bind<IHttpModule>().To<OnePerRequestHttpModule>();
}
}
ApplicationModule chúng tôi sống trong một dự án cơ sở hạ tầng riêng biệt với quyền truy cập vào tất cả các lớp khác nhau của chúng tôi, để xử lý DI & Lập bản đồ:
public class ApplicationModule: NinjectModule
{
public override void Load()
{
// IUnitOfWork/EF Setups
Bind<ApplicationContext>().ToSelf().InRequestScope();
Bind<IUnitOfWork>().ToMethod(ctx => ctx.Kernel.Get<ApplicationContext>()});
Bind<ApplicationContext>().ToMethod(ctx => ctx.Kernel.Get<ChromLimsContext>()}).WhenInjectedInto<IDal>();
// other bindings for dals and business objects, etc.
}
}
Sau đó, chúng tôi có một vài giao diện:
public interface IUnitOfWork()
{
void SaveChanges();
Task SaveChangesAsync();
}
và
public interface IDal()
{
// Crud operations, Sync and Async
}
sau đó các lớp học thực tế của chúng tôi sử dụng những:
public class SomeBusinessObject
{
private IUnitOfWork _uow;
private IDal _someDal;
public SomeBusinessObject(IUnitOfWork uow, IDal someDal)
{
_uow = uow;
_someDal = someDal;
}
public Task<SomeResult> SaveSomething(Something something)
{
_someDal.Save(something);
_uow.SaveChanges();
}
}
Một số Dal
public class SomeDal : IDal {
private ApplicationContext _applicationContext;
public SomeDal(ApplicationContext applicationContext)
{
_applicationContext = applicationContext;
}
public void Save(Something something)
{
_applicationContext.Somethings.Add(something);
}
}
EF chúng tôi DbContext
public class ApplicationContext : DbContext, IUnitOfWork
{
// EF DBSet Definitions
public void SaveChanges()
{
base.SaveChanges();
}
}
Hi vọng là cho mọi yêu cầu, một trường hợp duy nhất của ApplicationContext được tạo ra và tiêm vào các đối tượng kinh doanh như một thực hiện IUnitOfWork và vào IDals như một ApplicationContext.
Thay vào đó điều đang xảy ra là một phiên bản mới của ApplicationContext đang được tạo cho mỗi lớp đơn lẻ sử dụng nó. Nếu tôi chuyển đổi phạm vi từ InRequestScope thành InSingletonScope, thì (như mong đợi) chính xác 1 cá thể được tạo cho toàn bộ ứng dụng và được tiêm đúng vào các lớp được chỉ định. Kể từ đó hoạt động, tôi giả định đây không phải là một vấn đề ràng buộc, nhưng thay vì một vấn đề với phần mở rộng InRequestScope.
Vấn đề duy nhất tôi có thể tìm thấy tương tự với những gì tôi đang gặp phải là this one, nhưng tiếc là giải pháp không hoạt động. Tôi đã tham khảo tất cả các gói mà anh ta đã chỉ định trong cả dự án WebApi và Infrastructure, và tôi đã kiểm tra lại để chắc chắn rằng chúng đang được sao chép vào thư mục build.
Tôi đang làm gì sai?
Chỉnh sửa: Một số thông tin bổ sung. Nhìn vào mã nguồn Ninject trong cả hai Ninject.Web.WebApi.OwinHost và Ninject.Web.Common.OwinHost, có vẻ như Owin Middleware thêm OwinWebApiRequestScopeProvider làm IWebApiRequestScopeProvider. Nhà cung cấp này sau đó được sử dụng trong phương thức mở rộng InRequestScope() để trả về một phạm vi được đặt tên có tên là "Ninject_WebApiScope". Điều này sẽ có mặt cho đến khi lớp đích được tiêm vào công tắc. Phạm vi được đặt tên sau đó biến mất và phạm vi mới được tạo. Tôi nghĩ rằng đây có thể là những gì @BatteryBackupUnit đang đề cập đến trong nhận xét của họ, nhưng tôi không biết cách sửa nó.
tôi đoán sẽ là thứ hai 'Bind của bạn() 'gây ra điều này. Bạn không đặt nó thành 'InRequestScope()' –
LukeP
Thật không may là nó không hoạt động. Tôi cũng đã cố gắng chỉ ràng buộc các ApplicationContext cho chính nó InRequestScope, và sau đó chỉ ràng buộc IUnitOfWork ToMethod (ctx => ctx.Kernel.Get()). InRequestScope() –
aasukisuki
Liệu '.InRequestScope() 'làm việc cho bất kỳ * * ràng buộc? Có một vấn đề "được biết" liên quan đến việc cài đặt/nâng cấp gói nuget ninject, nơi nó không được thiết lập đúng và công cụ ninject cụ thể-phạm vi yêu cầu không được đăng ký chính xác. '.InRequestScope()' không có tác dụng - đáng buồn là thậm chí không ném một ngoại lệ. – BatteryBackupUnit