I use Unity as a dependency injection mechanism. It contains interfaces / classes for the repository and manager classes. These storages are responsible for receiving / saving / updating data from / to the database and for managers to know about object relationships with other components / classes.
Implemented by factory to get an instance of the dependency container (1 instance per request). When a repository / manager class is created, it receives a dependency container as a constructor parameter and can create all other managers / repositories if necessary.
There are two ways to create business objects:
- When data is retrieved from the database repository, instances of objects are created and initialized with the corresponding database data, including the "Container" field.
- When an object is created in code to be placed in a DB, among others, it accepts the "IUnityContainer" parameter.
As a result, in any case, any business object has a dependency container inside, and if it needs to receive any data, it can get an instance of the corresponding manager and request the required data.
Problem statement: Last week I read a few questions / answers about SO that say the following:
- object instances should not have access to the dependency container;
- instead, they should get all the necessary interfaces in the constructor.
, /: , .
, :
1: ""? ? ( , , , , , ).
2: ?
3. , ( Linq2Sql EF), DependencyContainer, ( , SQL-, , , SQL). ?
:
Manager:
public abstract class ManagerBase : IManager
{
protected ManagerBase(IUnityContainer container)
{
DependancyContainer = container;
}
protected readonly IUnityContainer DependancyContainer;
...
}
:
public abstract class RepositoryBase<T, TDb> : IRepository<T>
where T : IEntity
where TDb : class, IDbEntity, new()
{
protected abstract ITable<TDb> GetTable();
public IQueryable<T> GetAll()
{
return GetTable().Select(GetConverter());
}
, : , "":
public class CountryRepository
: RepositoryBase<ICountry, DbData.Country>, ICountryRepository
{
protected override Expression<Func<DbData.Country, ICountry>> GetConverter()
{
return dbEntity => new Country
{
DependancyContainer = DependancyContainer,
Code = dbEntity.CountryCode,
Name = dbEntity.CountryName,
};
}
, :
public class CountryManager : ManagerBase
{
ICountry GetCountryById(int countryId)
{
ICountryRepository repository = DependancyContainer.Resolve<ICountryRepository>();
return repository.GetAll()
.Where(country=>country.Id==countryId)
.SingleOrDefault()
;
}
}