0

I am using simple injector with nuget in asp.net mvc 5

Install-Package SimpleInjector -Version 3.1.5
Install-Package SimpleInjector.Integration.Web.Mvc -Version 3.1.5

In global.asax

 protected void Application_Start()
        {
            //removed for bravity
           // Container container = new DependencyInjectionContiner().DI();
            var container = new Container();
            container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();
            container.Register<IHomeRepository, HomeRepository>(Lifestyle.Scoped);

            //For WebApi Request
           // container.Register<IWebApi, WebApi>(Lifestyle.Transient);
            container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
            ////To verify life styles of injection
            container.Verify();
            DependencyResolver.SetResolver(
                new SimpleInjectorDependencyResolver(container));
        }

I showed error on

The configuration is invalid. The following diagnostic warnings were reported:

-[Lifestyle Mismatch] HomeRepository (Web Request) depends on UnitOfWork (Transient).

IHomeRepository

public interface IHomeRepository
    {
        void InsertDepartment(Department department, List<Student> students);
    }

HomeRepository

public class HomeRepository : IHomeRepository
    {
        private UnitOfWork unitOfWork;
        public HomeRepository(UnitOfWork unitOfWork)
        {
            this.unitOfWork = unitOfWork;
        }

        public void InsertDepartment(Department department, List<Student> students)
        {
            department.Students = students;
            unitOfWork.DepartmentRepository.Insert(department);
            unitOfWork.Save();
        }
}

IUnitOfWork

public class UnitOfWork : IDisposable
    {
        private SchoolContext context = new SchoolContext();
        private GenericRepository<Department> departmentRepository;
        private GenericRepository<Student> studentRepository;

        public GenericRepository<Department> DepartmentRepository
        {
            get
            {

                if (this.departmentRepository == null)
                {
                    this.departmentRepository = new GenericRepository<Department>(context);
                }
                return departmentRepository;
            }
        }

        public GenericRepository<Student> StudentRepository
        {
            get
            {

                if (this.studentRepository == null)
                {
                    this.studentRepository = new GenericRepository<Student>(context);
                }
                return studentRepository;
            }
        }

        public void Save()
        {
            context.SaveChanges();
        }

        private bool disposed = false;

        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    context.Dispose();
                }
            }
            this.disposed = true;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
    }

GenericRepository

public class GenericRepository<TEntity> where TEntity : class
    {
        internal SchoolContext context;
        internal DbSet<TEntity> dbSet;

        public GenericRepository(SchoolContext context)
        {
            this.context = context;
            this.dbSet = context.Set<TEntity>();
        }

        public virtual IEnumerable<TEntity> Get(
            Expression<Func<TEntity, bool>> filter = null,
            Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
            string includeProperties = "")
        {
            IQueryable<TEntity> query = dbSet;

            if (filter != null)
            {
                query = query.Where(filter);
            }

            foreach (var includeProperty in includeProperties.Split
                (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
            {
                query = query.Include(includeProperty);
            }

            if (orderBy != null)
            {
                return orderBy(query).ToList();
            }
            else
            {
                return query.ToList();
            }
        }

        //public IQueryable GetIQueryable()
        //{
        //    return context.Set<TEntity>().AsQueryable();
        //}
        public IEnumerable<TEntity> Query(Expression<Func<TEntity, bool>> filter)
        {
            return context.Set<TEntity>().Where(filter);
        }
        public IEnumerable<TEntity> Query()
        {
            return context.Set<TEntity>();
        }

        //public IQueryable Query()
        //{
        //    return context.Set<TEntity>();
        //}
        public virtual TEntity GetByID(object id)
        {
            return dbSet.Find(id);
        }

        public virtual void Insert(TEntity entity)
        {
            dbSet.Add(entity);
        }

        public virtual void Delete(object id)
        {
            TEntity entityToDelete = dbSet.Find(id);
            Delete(entityToDelete);
        }

        public virtual void Delete(TEntity entityToDelete)
        {
            if (context.Entry(entityToDelete).State == EntityState.Detached)
            {
                dbSet.Attach(entityToDelete);
            }
            dbSet.Remove(entityToDelete);
        }

        public virtual void Update(TEntity entityToUpdate)
        {
            dbSet.Attach(entityToUpdate);
            context.Entry(entityToUpdate).State = EntityState.Modified;
        }
    }

why verify shows the error? and Is it ok to use Transient and Scoped on a single container ????

Syed Mhamudul Hasan
  • 1,341
  • 2
  • 17
  • 45
  • The exception message contains this link https://simpleinjector.org/diagnostics to the documentation. Did you read that documentation? Do you have any questions after reading this documentation and especially [this](https://simpleinjector.readthedocs.io/en/latest/LifestyleMismatches.html)? – Steven Nov 27 '16 at 08:38
  • You mean to say make use of Hybrid Life style ? If so how to define it? – Syed Mhamudul Hasan Nov 27 '16 at 08:54

1 Answers1

2

The exception message refers to the following documentation page: https://simpleinjector.org/diagnostics. The documentation states the following about Lifestyle Mismatches:

In general, components should only depend on other components that are configured to live at least as long. In other words, it is safe for a transient component to depend on a singleton, but not the other way around. Since components store a reference to their dependencies in (private) instance fields, those dependencies are kept alive for the lifetime of that component. This means that dependencies that are configured with a shorter lifetime than their consumer, accidentally live longer than intended. This can lead to all sorts of bugs, such as hard to debug multi-threading issues.

The documentation also provides the following suggestions for fixes:

  • Change the lifestyle of the component to a lifestyle that is as short or shorter than that of the dependency.
  • Change the lifestyle of the dependency to a lifestyle as long or longer than that of the component.

This means you should either make the HomeRepository Transient, or make the UnitOfWork Scoped.

Making the UnitOfWork Scoped is the most obvious as discussed in this q&a.

You mean to say make use of Hybrid Life style

You should forget about hybrid lifestyles. They don't provide an answer to your problem.

Steven
  • 166,672
  • 24
  • 332
  • 435
  • One question ? It is ok to use WebRequestLife cycle or Transient Lifestyle for my Repository ? As i understand Transient can be memory consuming in IIS app pool – Syed Mhamudul Hasan Nov 27 '16 at 09:14
  • @syedmhamudulhasanakash: Where did you learn the transient can be memory consuming? An ASP.NET application spits out a lot of memory, the creation of a few extra repositories will be unnoticable for performance. Your `HomeRepository` will be 20 bytes in size. Typically nothing to worry about. – Steven Nov 27 '16 at 09:17
  • So are u suggesting to stick to `Transient` by the way , i just like your answer .Thanks man – Syed Mhamudul Hasan Nov 27 '16 at 09:19
  • 2
    @syedmhamudulhasanakash: No, what I'm suggesting is that you read [this](https://stackoverflow.com/questions/10585478/one-dbcontext-per-web-request-why) carefully and make an educated decision whether it is okay for your `UnitOfWork` to be Transient or not, and act accordingly. – Steven Nov 27 '16 at 09:23