Я уже некоторое время использую Unity в своем проекте MVC, успешно внедряя зависимости, подобные этой:
public interface IDepartmentRepository
{
//blah blah
}
public class DepartmentRepository: IDepartmentRepository
{
// blah blah
}
, в контроллеры и использую их для выполнения CRUD в базе данных SQL Compact с использованием EF CodeFirst, а также ведение журналаиспользуя NLog и другие вещи для моего приложения.
Но что, если я захочу внедрить их вне веб-приложения MVC в консольное приложение?Кажется, я что-то упускаю, когда я делаю это:
class Program
{
static void Main(string[] args)
{
UnityContainer container = new UnityContainer();
container.RegisterType<IContext, SCSMContext>(new PerResolveLifetimeManager());
container.RegisterType<IOrderRepository, OrderRepository>();
container.RegisterType<ILogger, NLogLogger>();
container.RegisterType<IDoSomething, DoSomething>();
DoSomething foo = (DoSomething)container.Resolve<IDoSomething>();
}
}
public interface IDoSomething
{
}
class DoSomething: IDoSomething
{
IOrderRepository orderRepository;
IOrderFileUploadRepository orderFileUploadRepository;
IContext unitOfWork;
ILogger logger;
public DoSomething(IOrderRepository orderRepository,
IContext unitOfWork,
ILogger logger)
{
this.orderRepository = orderRepository;
this.unitOfWork = unitOfWork;
this.logger = logger;
logger.LogInfo("Logging from an external project!");
orderRepository.Add(new Order() {OrderName="foo"});
unitOfWork.CommitChanges();
// These lines run and give no exceptions
// But nothing gets logged or inserted
orderRepository.GetAll();
//Returns an empty list, when there are orders in db.
}
}
}
Спасибо!
РЕДАКТИРОВАТЬ:
Классы ILogger и NLogLogger:
public interface ILogger
{
void LogInfo(string message, params object[] args);
void LogWarning(string message, params object[] args);
void LogError(string message, Exception exception, params object[] args);
}
public class NLogLogger : ILogger
{
private Logger _logger;
public NLogLogger()
{
_logger = LogManager.GetCurrentClassLogger();
}
public void LogInfo(string message, params object[] args)
{
_logger.Info(message);
}
public void LogWarning(string message, params object[] args)
{
_logger.Warn(message);
}
public void LogError(string message, Exception exception, params object[] args)
{
_logger.Error(message + LogUtility.BuildExceptionMessage(exception));
}
}
Примечание. Этот проект - проект, над которым работал другой человек, а затем ушел. Я все еще выясняю, как все это работает, извините, если я игнорирую некоторые вещи.
Классы IContext и SCSMContext кажутся мне слишком глубокими для полного понимания, вот они:
IContext:
public interface IContext : IQueryableUnitOfWork
{
IDbSet<Location> Locations { get; }
IDbSet<Department> Departments { get; }
IDbSet<Requisition> Requisitions { get; }
IDbSet<RequisitionAttachment> RequisitionAttachments { get; }
IDbSet<RequisitionItem> RequisitionItems { get; }
IDbSet<RequisitionComment> RequisitionComments { get; }
IDbSet<Order> Orders{ get; }
IDbSet<OrderItem> OrderItems { get; }
IDbSet<OrderFileUpload> OrderFileUploads { get; }
IDbSet<Transaction> Transactions { get; }
IDbSet<DispatchNote> DispatchNotes { get; }
IDbSet<DispatchItem> DispatchItems { get; }
IDbSet<LocationsInRolesForUser> LocationsInRolesForUser { get; }
}
SCSMContext:
public class SCSMContext : System.Data.Entity.DbContext, IContext
{
#region IContext Members
IDbSet<Order> _orders;
public IDbSet<Order> Orders
{
get
{
if (_orders == null)
_orders = base.Set<Order>();
return _orders;
}
}
//Other IContext definitions......
#endregion
#region IQueryableUnitOfWork Members
public IDbSet<T> CreateSet<T>()
where T : class
{
return base.Set<T>();
}
public void Attach<T>(T item)
where T : class
{
//attach and set as unchanged
base.Entry<T>(item).State = System.Data.EntityState.Unchanged;
}
public void SetModified<T>(T item)
where T : class
{
//this operation also attach item in object state manager
base.Entry<T>(item).State = System.Data.EntityState.Modified;
}
public void ApplyCurrentValues<T>(T original, T current)
where T : class
{
//if not is attached, attach original and set current values
base.Entry<T>(original).CurrentValues.SetValues(current);
}
public void CommitChanges()
{
base.SaveChanges();
}
public void RollbackChanges()
{
// set all entities in change tracker
// as 'unchanged state'
base.ChangeTracker.Entries()
.ToList()
.ForEach(entry => entry.State = System.Data.EntityState.Unchanged);
}
public IEnumerable<T> ExecuteQuery<T>(string sqlQuery, params object[] parameters)
{
return base.Database.SqlQuery<T>(sqlQuery, parameters);
}
public int ExecuteCommand(string sqlCommand, params object[] parameters)
{
return base.Database.SqlCommand(sqlCommand, parameters);
}
#endregion
}
Кроме того, IQueryableUnitOfWork: (на всякий случай?)
public interface IQueryableUnitOfWork : IUnitOfWork, ISql
{
/// <summary>
/// Returns a IDbSet instance for access to entities of the given type in the context,
/// the ObjectStateManager, and the underlying store.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
IDbSet<T> CreateSet<T>() where T : class;
/// <summary>
/// Attach this item into "ObjectStateManager"
/// </summary>
/// <typeparam name="T">The type of entity</typeparam>
/// <param name="item">The item <</param>
void Attach<T>(T item) where T : class;
/// <summary>
/// Set object as modified
/// </summary>
/// <typeparam name="T">The type of entity</typeparam>
/// <param name="item">The entity item to set as modifed</param>
void SetModified<T>(T item) where T : class;
/// <summary>
/// Apply current values in <paramref name="original"/>
/// </summary>
/// <typeparam name="T">The type of entity</typeparam>
/// <param name="original">The original entity</param>
/// <param name="current">The current entity</param>
void ApplyCurrentValues<T>(T original, T current) where T : class;
}
Извините за огромный пост: \