MVC3 + Ninject + Entity Framework 4 - PullRequest
       17

MVC3 + Ninject + Entity Framework 4

3 голосов
/ 22 февраля 2011

У меня есть этот преобразователь зависимостей

public class NinjectDependencyResolvercs : IDependencyResolver
    {
        private readonly IResolutionRoot resolutionRoot;
        public NinjectDependencyResolvercs(IResolutionRoot kernel)
        {
            resolutionRoot = kernel;
        }

        public object GetService(Type serviceType)
        {
            return resolutionRoot.TryGet(serviceType);
        }

        public IEnumerable<object> GetServices(Type serviceType)
        {
            return resolutionRoot.GetAll(serviceType);
        }
    }

в global.asax.cs

// Ninject DI container ----------------------------------------------------------- |
        public void SetupDependencyInjection()
        {
            // Create Ninject DI kernel
            IKernel kernel = new StandardKernel();

            #region Register services with Ninject DI Container

            // DbContext to SqlDataContext
            kernel.Bind<DbContext>()
                    .To<SqlDataContext>();

            // IRepository to SqlRepository
            kernel.Bind<IRepository>()
                    .To<SqlRepository>();

            // IUsersServices to UsersServices
            kernel.Bind<IUsersServices>()
                    .To<UsersServices>();

            // IMessagesServices to MessagesServices
            kernel.Bind<IMessagesServices>()
                    .To<MessagesServices>();

            // IJobAdvertsServices to JobAdvertsServices
            kernel.Bind<IJobAdvertsServices>()
                    .To<JobAdvertsServices>();

            #endregion

            // Tell ASP.NET MVC 3 to use Ninject DI Container
            DependencyResolver.SetResolver(new NinjectDependencyResolvercs(kernel));
        }
        // --------------------------------------------------------------------------------- |

и классе

public class SqlDataContext : DbContext
    {
        public DbSet<User> Users { get; set; }
        public DbSet<Profile> Profiles { get; set; }
        public DbSet<Role> Roles { get; set; }
        public DbSet<JobAdvert> JobAdverts { get; set; }
        public DbSet<Message> Messages { get; set; }

        protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<User>().HasMany(x => x.Roles).WithMany(x => x.Users).Map(x =>
            {
                x.MapLeftKey(y => y.UserId, "UserId");
                x.MapRightKey(y => y.RoleId, "RoleId");
                x.ToTable("UsersInRoles");
            });

            base.OnModelCreating(modelBuilder);
        }
    }

все зависимости работают нормально, но для DbContextSqlDataContext это проблема.Если использовать это:

public class SqlRepository
{
    private DbContext dataContext;
    public SqlRepository(DbContext dataContext) {
        this.dataContext = dataContext;
    }

    public DbSet<User> Users {
        get {
            return dataContext.Users;
        }
    }
}

, то

dataContext.Users

и все другие свойства предупреждают об этой ошибке:

'System.Data.Entity.DbContext' does not contain a definition for 'JobAdverts' and no extension method 'JobAdverts' accepting a first argument of type 'System.Data.Entity.DbContext' could be found (are you missing a using directive or an assembly reference?)   

Есть кто-нибудь, кто знает, почему DI работает для классаDbContext?

1 Ответ

4 голосов
/ 22 февраля 2011

Если я правильно понимаю, вы вводите DbContext, у которого нет этих методов / свойств, поскольку они объявлены в производном типе SqlDataContext. Вам нужно ввести SqlDataContext. Если вы хотите использовать интерфейс, вам нужно извлечь интерфейс из SqlDataContext.

EDIT:

Ninject связывается в время выполнения , в то время как ошибки, которые вы получаете (я полагаю), находятся в время компиляции . Вы можете обойти это, используя динамическое ключевое слово, но это просто работает вокруг проблемы.

public class SqlRepository
{
    private dynamic dataContext;
    public SqlRepository(DbContext dataContext) {
        this.dataContext = dataContext;
    }
    ...
}

Что вам нужно сделать, это изменить подпись для использования вашего SqlDataContext:

public class SqlRepository
{
 private SqlDataContextdata Context;
    public SqlRepository(SqlDataContextdata Context) {
        this.dataContext = dataContext;
    }
  ...
}

, поскольку DbContext не содержит этих методов, только ваш SqlContext содержит. и ваш sqlcontext привязан к DbContext в время выполнения .

...