Here is my project responsible for data:
public interface IRepository<T> where T : class
{
IQueryable<T> All();
T GetById(int id);
void Add(T entity);
void Update(T entity);
....
}
EF implement IRepository
public class GenericRepository<T> : IRepository<T> where T : class
{
public GenericRepository() : this(new ApplicationDbContext())
{
}
public GenericRepository(DbContext context)
{
if (context == null)
{
throw new ArgumentException("An instance of DbContext is required to use this repository.", "context");
}
this.Context = context;
this.DbSet = this.Context.Set<T>();
}
protected IDbSet<T> DbSet { get; set; }
protected DbContext Context { get; set; }
public virtual IQueryable<T> All()
{
return this.DbSet.AsQueryable();
}
public virtual T GetById(int id)
{
return this.DbSet.Find(id);
}........
I use unit of work pattern
public interface IUowData : IDisposable
{
IRepository<House> Houses { get; }
IRepository<Floor> Floors { get; }
...
int SaveChanges();
}
And this is his implementation
public class UowData:IUowData
{
private readonly DbContext context;
private readonly Dictionary<Type, object> repositories = new Dictionary<Type, object>();
public UowData(){}
public UowData(DbContext context)
{
this.context = context;
}
private IRepository<T> GetRepository<T>() where T : class
{
if (!this.repositories.ContainsKey(typeof(T)))
{
var type = typeof(GenericRepository<T>);
this.repositories.Add(typeof(T), Activator.CreateInstance(type, this.context));
}
return (IRepository<T>)this.repositories[typeof(T)];
}
public int SaveChanges()
{
return this.context.SaveChanges();
}
public void Dispose()
{
this.context.Dispose();
}
The second project is of type Web API through which I try to access data from database:
public class ArduinoController : ApiController
{
private IEmailSender sender;
private IUowData data;
public ArduinoController(IEmailSender sender, IUowData data)
{
this.sender = sender;
this.data = data;
}
[HttpPost]
[ActionName("PostAlarm")]
public void PostAlarm(dynamic sensorJson)
{
var alartModel = this.data.Sensors.All()
.....
When I try to use Ninject dependancy resolve i get exception:
"The context cannot be used while the model is being created. This exception may be thrown if the context is used inside the OnModelCreating method or if the same context instance is accessed by multiple threads concurrently. Note that instance members of DbContext and related classes are not guaranteed to be thread safe.".
Everything works fine if I fetch one page at a time. I am using a simple tool 'XENU' to fetch multiple pages simultaneously. This is when I get errors with DBContext by fetching multiple pages at a time.
public static class NinjectWebCommon
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}
public static void Stop()
{
bootstrapper.ShutDown();
}
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver = new Ninject.WebApi.DependencyResolver.NinjectDependencyResolver(kernel);
return kernel;
}
private static void RegisterServices(IKernel kernel)
{
EmailSettings emailSettings = new EmailSettings
{
ServerName = Settings.Default.EmailServerName,
...
};
kernel.Bind<IEmailSender>().To<EmailSender>().WithConstructorArgument("settings", emailSettings);
kernel.Bind<IUowData>().To<UowData>().InRequestScope().WithConstructorArgument("context",new ApplicationDbContext());
}
}
.WithConstructorArgument("context",new ApplicationDbContext());
results in one DB Context for the whole application. Remove that and add a binding instead.
.Bind<DbContext>().To<ApplicationDbContext>().InRequestScope();
Related
I am trying to implement dependency injection in web api 2 but unable to do so. Getting object reference not set error.
Here is my implementatoin
Model:
public class Product
{
.....
}
Interface:
public interface IProductRepository
{
IEnumerable<Product> GetAll();
.....
}
Interface Implementation:
public class ProductRespository : IProductRepository, IDisposable
{
private ApiContext _context;
public ProductRespository(ApiContext context)
{
this._context = context;
}
public ProductRespository()
{
}
public IEnumerable<Product> GetAll()
{
return _context.Products.OrderBy(o => o.Name);
}
......
}
And Ninjectwebcommon.cs class:
public static class NinjectWebCommon
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
public static void Start(){....}
.....
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver = new Ninject.WebApi.DependencyResolver.NinjectDependencyResolver(kernel);
RegisterServices(kernel);
return kernel;
}
private static void RegisterServices(IKernel kernel)
{
//kernel.Bind<IRepo>().ToMethod(ctx => new Repo("Ninject Rocks!"));
kernel.Bind<ApiContext>().ToSelf().InRequestScope();
kernel.Bind<IProductRepository>().To<ProductRespository>().InRequestScope();
}
}
And finally in my controller ProductController:
public class ProductController : ApiController
{
private IProductRepository _productRepository = null;
public ProductController(IProductRepository productRepository)
{
_productRepository = productRepository;
}
public ProductController()
{
}
public IHttpActionResult GetAllProducts()
{
return Ok(_productRepository.GetAll());
}
}
When getallproducts controller method is hit i get this exception
System.NullReferenceException: 'Object reference not set to an instance of an object.'
I think this is related to your interface in ProductController.
Try like this:
public IProductRepository _productRepository { get; set; }
I had the same problems, but using given codeline helped me / us out.
I'm using MVC pattern in my application. For each model class I have a controller one. All controller classes have a saveOrUpdate() method. I am wondering if this is enough to create an Interface which defines said method, and then all controller implements it.
Please note that saveOrUpdate() receive a model class as a parameter. So it would be something like UserController#saveOrUpdate(User user), CourseController#saveOrUpdate(Course course), AppleManager#saveOrUpdate(Apple apple).
I think what you need is generic repository which implements generic functionality for a given entity. I've recently started implementing Repository Pattern along with Unit of Work in my MVC projects. Here is how I do that.
MyDbContext.cs:
public class MyDbContext : DbContext
{
public MyDbContext() : base("name=DefaultConnection”)
{
}
public System.Data.Entity.DbSet<User> Users { get; set; }
public System.Data.Entity.DbSet<Course> Courses { get; set; }
}
Unit of Work:
public class UnitOfWork : IUnitOfWork
{
//private variable for db context
private MyDbContext _context;
//initial db context variable when Unit of Work is constructed
public UnitOfWork()
{
_context = new MyDbContext();
}
//property to get db context
public MyDbContext Context
{
//if not null return current instance of db context else return new
get { return _context ?? (_context = new MyDbContext()); }
}
//save function to save changes using UnitOfWork
public void Save()
{
_context.SaveChanges();
}
}
Generic Repository:
public class RepositoryBase<T> : IRepositoryBase<T> where T : class
{
protected readonly IUnitOfWork _unitOfWork;
private readonly IDbSet<T> _dbSet;
public RepositoryBase(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
_dbSet = _unitOfWork.Context.Set<T>();
}
public virtual void Save()
{
_unitOfWork.Save();
}
public virtual void Add(T entity)
{
_dbSet.Add(entity);
_unitOfWork.Save();
}
//Similarly you can have Update(), Delete(), GetAll() implementation here
}
Entity Repository inheriting from generic repo:
public class UserRepository:RepositoryBase<User>,IUserRepository
{
public UserRepository(IUnitOfWork unitOfWork) : base(unitOfWork)
{
}
//Here you can also define functions specific to User
}
Controller:
public class UserController : Controller
{
private readonly IUserRepository _dbUserRepository;
public UserController(IUserRepository dbUserRepository)
{
_dbUserRepository = dbUserRepository;
}
// GET: /User/
public ActionResult Index()
{
var users = _dbUserRepository.GetAll();
return View(users.ToList());
}
}
create an interface
interface ISave
{
void Save(object obj);
}
now in your controller implement it.
public class AppleControler : Controller , ISave
{
public void Save(Object obj)
{
//you can cast your object here.
}
}
Option two
interface ISave<T>
{
void Save(T obj);
}
public class AppleControler : Controller , ISave<Apple>
{
public void Save(Apple obj)
{
}
}
Lets say I have 2 tables. ProductCategory and Product. I have 1 generic repository that can handle both tables:
public class GenericRepository<T> : IRepository<T>
But when using unit of work pattern, am I forced to create a repository for ALL tables in my database?
public interface IUnitOfWork : IDisposable
{
int SaveChanges();
IRepository<ProductCategory> ProductCategoryRepository { get; }
IRepository<Product> ProductRepository { get; }
}
Is there not a way I can add the generic repository to the unit of work class?
You can add a generic method to the IUnitOfWork interface:
public interface IUnitOfWork : IDisposable
{
int SaveChanges();
IRepository<T> Repository<T>();
}
But i don't recommend it. It's smells like Service Locator anti-pattern and SRP violation. Better way is to remove all repositories from the IUnitOfWork interface, because providing access to repository is not UnitOfWork's responsibility. I recommend to separate repository from UnitOfWork and inject their into the consumer by itself.
public class Consumer
{
private readonly IUnitOfWork _unitOfWork;
private readonly IRepository<Product> _products;
public Consumer(IUnitOfWork unitOfWork, IRepository<Product> products)
{
_unitOfWork = unitOfWork;
_products = products;
}
public void Action()
{
var product = _products.GetOne();
product.Name = "new name";
_products.Update(product);
_unitOfWork.SaveChanges();
}
}
UDATE:
UnitOfWork and Repository can share context instance.
Here the sample of code:
public class EfUnitOfWork : IUnitOfWork
{
private readonly DbContext _context;
public EfUnitOfWork(DbContext context)
{
_context = context;
}
public void SaveChanges()
{
_context.SaveChanges();
}
}
public class EfRepository<T> : IRepository<T> where T : class
{
private readonly DbContext _context;
public EfRepository(DbContext context)
{
_context = context;
}
//... repository methods...
}
public class Program
{
public static void Main()
{
//poor man's dependency injection
var connectionString = "northwind";
var context = new DbContext(connectionString);
var unitOfWork = new EfUnitOfWork(context);
var repository = new EfRepository<Product>(context);
var consumer = new Consumer(unitOfWork, repository);
consumer.Action();
}
}
Demonstrating a solution with only one class would be
public class Session : ISession
{
private readonly DbContext _dbContext;
public Session(DbContext dbContext)
{
_dbContext = dbContext;
}
public TEntity Single<TEntity>(Expression<Func<TEntity, bool>> expression) where TEntity : class
{
return _dbContext.Set<TEntity>().SingleOrDefault(expression);
}
public IQueryable<TEntity> Query<TEntity>() where TEntity : class
{
return _dbContext.Set<TEntity>().AsQueryable();
}
public void Commit()
{
try { _dbContext.SaveChanges(); }
catch (DbEntityValidationException ex)
{
var m = ex.ToFriendlyMessage();
throw new DbEntityValidationException(m);
}
}
public void Dispose()
{
_dbContext.Dispose();
}
public void Add<TEntity>(IEnumerable<TEntity> items) where TEntity : class
{
items.ToList().ForEach(Add);
}
public void Add<TEntity>(TEntity item) where TEntity : class
{
_dbContext.Set<TEntity>().Add(item);
}
public void Remove<TEntity>(TEntity item) where TEntity : class
{
_dbContext.Set<TEntity>().Remove(item);
}
public void Remove<TEntity>(Expression<Func<TEntity, bool>> expression) where TEntity : class
{
var items = Query<TEntity>().Where(expression);
Remove<TEntity>(items);
}
public void Remove<TEntity>(IEnumerable<TEntity> items) where TEntity : class
{
items.ToList().ForEach(Remove);
}
}
and then your usage can be
public class User
{
public int? Id { get; set; }
public string Name { get; set; }
public DateTime Dob { get; set; }
}
public class Usage
{
private readonly ISession _session;
public Usage(ISession session) { _session = session; }
public void Create(User user)
{
_session.Add(user);
_session.Commit();
}
public void Update(User user)
{
var existing = _session.Single<User>(x => x.Id == user.Id);
// this gets cumbursome for an entity with many properties.
// I would use some thing like valueinjecter (nuget package)
// to inject the existing customer values into the one retreived from the Db.
existing.Name = user.Name;
existing.Dob = user.Dob;
_session.Commit();
}
}
I have deliberately not included a Repository class. To have a class encapsulate both queries and commands for every entity is an over kill and a needless abstraction. Its almost a design flaw at a fundamental level. Queries and commands are fundamentally different concerns. Queries in the most simplest manner can be created as extensions methods on the ISession interface. Commands can be done using a few classes like such..
public interface ICommand<in TSource>
{
void ApplyTo(TSource source);
}
public interface ICommandHandler<out TSource>
{
void Handle(ICommand<TSource> command);
}
public class LinqCommandHandler : ICommandHandler<IStore>
{
private readonly ISession _session;
public LinqCommandHandler(ISession session)
{
_session = session;
}
public void Handle(ICommand<IStore> command)
{
command.ApplyTo(_session);
_session.Commit();
}
}
public class UpdateDobForUserName : ICommand<IStore>
{
public string UserName { get; set; }
public DateTime Dob { get; set; }
public void OnSend(IStore store)
{
var existing = store.Query<User>().SingleOrDefault(x => x.Name == UserName);
existing.Dob = Dob;
}
}
public class Usage
{
private readonly ICommandHandler<IStore> _commandHandler;
public Usage(ICommandHandler<IStore> commandHandler)
{
_commandHandler = commandHandler;
}
public void Update()
{
var command = new UpdateDobForUserName {UserName = "mary", Dob = new DateTime(1960, 10, 2)};
_commandHandler.Handle(command);
}
}
The IStore above is the same as the Session class, except that it doesn't implement the IDisposable interface and doesn't have a Commit() method. The ISession then obviously inherits from an IStore and also implements IDisposable and has one method Commit(). This ensures an ICommand<IStore> can never open or dispose connections and cannot commit. Its responsibility is to define a command and define how its applied. Who applies it and what happens and what not on command application is a different responsibility which is with the ICommandHandler<IStore>.
There are many ways to implement Unit of work. I prefer having the repositories take a Unit of Work in its constructor (which is passed via Dependency Injection), then you only create repositories for your needs.
My question is very similar to this one: MVC3 tool using Entity Framework caching issues with Ninject however my mapping is a bit more complex and when I use InRequestScope I get the following error:
The operation cannot be completed because the DbContext has been disposed.
If I don't include InRequestScope everything works except EF Code First seems to cache my entities and it doesn't match up to the values in the Db.
Here's my ninject mapping I'm using the ninject mvc3 nuget package (without InRequestScope):
kernel.Bind<MyContext>()
.ToSelf()
.WithConstructorArgument("connectionString", context => MvcApplication.GetConnectionStringName);
kernel.Bind<IUnitOfWork>().To<UnitOfWork>();
// Service Layer.
kernel.Bind<ICustomerService>().To<CustomerService>();
kernel.Bind<IMessageService>().To<MessageService>();
kernel.Bind<IUserService>().To<UserService>();
// Repository Layer.
kernel.Bind<IRepository<Customer>>().To<GenericRepository<Customer>>();
kernel.Bind<IRepository<Message>>().To<GenericRepository<Message>>();
kernel.Bind<IRepository<User>>().To<GenericRepository<User>>();
NinjectContainer.Initialize(kernel);
My IUnitOfWork
public interface IUnitOfWork
{
IUserService UserService { get; }
ICustomerService CustomerService { get; }
IMessageService MessageService { get; }
void CommitChanges();
}
My UnitOfWork
public class UnitOfWork : IUnitOfWork
{
MyContext _context;
private readonly IUserService _userService;
private readonly ICustomerService _customerService;
private IMessageService _messageService;
public UnitOfWork(IUserService userService,
ICustomerService customerService,
IMessageService messageService,
MyContext context)
{
_userService = userService;
_customerService = customerService;
_messageService = messageService;
SetContext(optimaContext);
}
private void SetContext(MyContext context)
{
_context = context;
_userService.Context = _context;
_customerService.Context = _context;
_messageService.Context = _context;
}
public void CommitChanges()
{
_context.SaveChanges();
}
public IUserService UserService { get { return _userService; } }
public ICustomerService CustomerService { get { return _customerService; } }
public IMessageService MessageService { get { return _messageService; } }
}
My ICustomerService
public interface ICustomerService
{
DbContext Context { get; set; }
IQueryable<Customer> All();
}
My CustomerService
public class CustomerService : ICustomerService
{
IRepository<Customer> _customerRepo;
public CustomerService(IRepository<Customer> customerRepo)
{
_customerRepo = customerRepo;
}
private DbContext _context;
public DbContext Context
{
get { return _context; }
set { _context = value; _customerRepo.Context = value; }
}
public IQueryable<Customer> All()
{
return _customerRepo.All();
}
}
My other services follow a similar patter.
My IRepository
public interface IRepository<T> where T : class, new()
{
DbContext Context { get; set; }
T Single(Expression<Func<T, bool>> expression);
T Find(object id);
IQueryable<T> All();
void Delete(Expression<Func<T, bool>> expression);
void Delete(T item);
}
My Repository
public class GenericRepository<T> : IRepository<T> where T : class, new()
{
DbContext _context;
public DbContext Context
{
get { return _context; }
set { _context = value; }
}
public virtual T Single(Expression<Func<T, bool>> expression)
{
return All().FirstOrDefault(expression);
}
public virtual T Find(object id)
{
return _context.Set<T>().Find(id);
}
public virtual IQueryable<T> All()
{
return _context.Set<T>();
}
public virtual void Delete(Expression<Func<T, bool>> expression)
{
var items = All().Where(expression);
foreach (var item in items)
{
Delete(item);
}
}
public virtual void Delete(T item)
{
_context.Set<T>().Remove(item);
}
}
If anyone can help with the Ninject mapping and the correct way to inject classes it would be greatly appreciated.
I found the problem, I was using the [Inject] attribute with a FilterAttribute when the attribute was being called it was before my context had been initialised and that producted the dbContext error.
I followed the wiki on the ninject github site here to setup ninject on FilterAttribute. On issue I did have was finding the BindFilter method, this is hidden away Ninject.Web.Mvc.FilterBindingSyntax namespace.
My ninject mappings now look like:
kernel.Bind<MyContext>()
.ToSelf()
.InRequestScope()
.WithConstructorArgument("connectionString", context => MvcApplication.GetConnectionStringName);
kernel.Bind<IUnitOfWork>().To<UnitOfWork>();
// Service Layer.
kernel.Bind<ICustomerService>().To<CustomerService>();
kernel.Bind<IMessageService>().To<MessageService>();
kernel.Bind<IUserService>().To<UserService>();
// Repository Layer.
kernel.Bind<IRepository<Customer>>().To<GenericRepository<Customer>>();
kernel.Bind<IRepository<Message>>().To<GenericRepository<Message>>();
kernel.Bind<IRepository<User>>().To<GenericRepository<User>>();
// Attributes
kernel.BindFilter<AuthorizeWithTokenAttribute>(FilterScope.Controller, 0)
.WhenControllerHas<AuthorizeWithTokenFilter>()
.WithConstructorArgumentFromControllerAttribute<AuthorizeWithTokenFilter>("roles", attribute => attribute.Roles)
.WithConstructorArgumentFromControllerAttribute<AuthorizeWithTokenFilter>("users", attribute => attribute.Users);
If I have the following setup, how can I configure my container to use the same database, when objects are created in the same context
public class Database { }
public interface IRepository { Database Database { get; } }
public interface IFooRepository : IRepository { }
public interface IBarRepository : IRepository { }
public class FooRepository : IFooRepository
{
public Database Database { get; private set; }
public FooRepository(Database database) { this.Database = database; }
}
public class BarRepository : IBarRepository
{
public Database Database { get; private set; }
public BarRepository(Database database) { this.Database = database; }
}
public class Consumer
{
public IFooRepository fooRepository { get; private set; }
public IBarRepository barRepository { get; private set; }
public Consumer(IFooRepository fooRepository, IBarRepository barRepository)
{
this.fooRepository = fooRepository;
this.barRepository = barRepository;
}
}
[TestClass]
public class ConfigurationTest
{
private IWindsorContainer container;
[TestMethod]
public void SameDatabaseIsUsed()
{
Consumer consumer = container.Resolve<Consumer>();
IFooRepository fooRepository = consumer.fooRepository;
IBarRepository barRepository = consumer.barRepository;
Assert.AreEqual(fooRepository.Database, barRepository.Database); //FAILS
}
[TestMethod]
public void DifferentDatabaseIsUsed()
{
Consumer consumer = container.Resolve<Consumer>();
IFooRepository fooRepository = consumer.fooRepository;
Consumer consumer2 = container.Resolve<Consumer>();
IBarRepository barRepository = consumer2.barRepository;
Assert.AreNotEqual(fooRepository.Database, barRepository.Database); //PASSES
}
[TestInitialize]
public void SetUp()
{
container = new WindsorContainer();
container.Register(
Component.For<Database>().ImplementedBy<Database>().LifeStyle.Transient,
AllTypes.FromThisAssembly()
.BasedOn<IRepository>().WithService.FromInterface()
.Configure(c => c.LifeStyle.Transient),
Component.For<Consumer>().ImplementedBy<Consumer>().LifeStyle.Transient
);
}
}
EDIT:
I have tried to use a custom lifestyle, but i cannot figure out what I can use to detect that i have switched context
public class DatabaseLifestyleManager : AbstractLifestyleManager
{
private CreationContext context;
private Database database;
private Database Database
{
get
{
if (database == null) database = new Database();
return database;
}
set
{
database = null;
}
}
public override object Resolve(CreationContext context)
{
if (this.context!=null && this.context.??? == context.???)
return Database;
else
{
this.context = context;
Database = null;
return Database;
}
}
public override void Dispose()
{
database = null;
context = null;
}
}
......
Component.For<Database>().ImplementedBy<Database>().LifeStyle.Custom(typeof(DatabaseLifestyleManager)
You always get a new instance when requesting a transient component, if it's not what you want don't use the transient lifestyle :-)
Why would you register a transient component, but attempt to resolve the same object depending on some kind of "context"? Most likely the lifestyle is wrong for the situation, and you will be in trouble trying to coerce it into something it's not.
What you want is something like a contextual lifestyle, mentioned in this article.
The below two gists have an implementation for this:
http://gist.github.com/400979
http://gist.github.com/400980
This will allow you do this:
Register(Component.For<Database>().LifeStyle.Scoped())
[TestMethod]
public void SameDatabaseIsUsed()
{
using (container.BeginScope())
{
Consumer consumer = container.Resolve<Consumer>();
IFooRepository fooRepository = consumer.fooRepository;
IBarRepository barRepository = consumer.barRepository;
Assert.AreEqual(fooRepository.Database, barRepository.Database); // YAY!
}
}
Hope this helps!
A contextual lifestyle is included in the Castle.Windsor.Lifestyles contrib project.
I came up with this solution myself by implementing IDisposable, so that I can use a kind of sessionscope for the Database
Would this be a valid way to handle this situation?
All test passes, but there is some added functionality, that must be implemented in all my future consumers of the repositories:
public class Database { }
public interface IRepository : IDisposable { Database Database { get; } }
public interface IFooRepository : IRepository { }
public interface IBarRepository : IRepository { }
public abstract class BaseRepository : IDisposable
{
public BaseRepository(Database database) { this.Database = database; }
public Database Database { get; private set; }
public void Dispose() { Database = null; }
}
public class FooRepository : BaseRepository, IFooRepository
{
public FooRepository(Database database) : base(database) { }
}
public class BarRepository : BaseRepository, IBarRepository
{
public BarRepository(Database database) : base(database) { }
}
public abstract class BaseConsumer : IDisposable
{
public abstract void Dispose();
}
public class Consumer : BaseConsumer
{
public IFooRepository fooRepository { get; private set; }
public IBarRepository barRepository { get; private set; }
public Consumer(IFooRepository fooRepository, IBarRepository barRepository)
{
this.fooRepository = fooRepository;
this.barRepository = barRepository;
}
public override void Dispose()
{
this.fooRepository.Dispose();
this.barRepository.Dispose();
}
}
[TestClass]
public class ConfigurationTest
{
private IWindsorContainer container;
[TestMethod]
public void SameDatabaseIsUsed()
{
IFooRepository fooRepository;
IBarRepository barRepository;
using (Consumer consumer = container.Resolve<Consumer>())
{
fooRepository = consumer.fooRepository;
barRepository = consumer.barRepository;
Assert.AreEqual(fooRepository.Database, barRepository.Database); //FAILS
}
Assert.IsNull(fooRepository.Database);
Assert.IsNull(barRepository.Database);
}
[TestMethod]
public void DifferentDatabaseIsUsed()
{
IFooRepository fooRepository;
IBarRepository barRepository;
using (Consumer consumer = container.Resolve<Consumer>())
fooRepository = consumer.fooRepository;
Assert.IsNull(fooRepository.Database);
using (Consumer consumer2 = container.Resolve<Consumer>())
barRepository = consumer2.barRepository;
Assert.IsNull(barRepository.Database);
}
[TestInitialize]
public void SetUp()
{
container = new WindsorContainer().Register(
Component.For<Database>().ImplementedBy<Database>().LifeStyle.Singleton,
AllTypes.FromThisAssembly()
.BasedOn<IRepository>().WithService.FromInterface()
.Configure(c => c.LifeStyle.Transient),
Component.For<Consumer>().ImplementedBy<Consumer>().LifeStyle.Transient
);
}
}