Model view controller 在MVC中使用Unity。如何将其依赖项注入其他地方?

Model view controller 在MVC中使用Unity。如何将其依赖项注入其他地方?,model-view-controller,dependency-injection,unity-container,console-application,Model View Controller,Dependency Injection,Unity Container,Console Application,我在MVC项目中使用Unity已有一段时间了,成功地注入了如下依赖项: public interface IDepartmentRepository { //blah blah } public class DepartmentRepository: IDepartmentRepository { // blah blah } 进入控制器,并使用它们在SQL Compact数据库上使用EF CodeFirst执行CRUD,还使用NLog进行日志记录,以及我的应用程序的其他内容 但是,如果我

我在MVC项目中使用Unity已有一段时间了,成功地注入了如下依赖项:

public interface IDepartmentRepository
{
 //blah blah
} 
public class DepartmentRepository: IDepartmentRepository
{
// blah blah
}
进入控制器,并使用它们在SQL Compact数据库上使用EF CodeFirst执行CRUD,还使用NLog进行日志记录,以及我的应用程序的其他内容

但是,如果我想将MVC webapp之外的应用程序注入控制台应用程序,该怎么办?当我这样做的时候,似乎我遗漏了什么:

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.
    }
}
注:此项目是其他人参与的项目,然后离开。。 我还在弄清楚整个事情是怎么回事,如果我忽略了一些事情,对不起

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; }

}
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


}
公共接口IContext:IQueryableUnitOfWork
{
IDbSet位置{get;}
IDbSet部门{get;}
IDbSet请求{get;}
IDbSet RequisitionAttachments{get;}
IDbSet requisionItems{get;}
IDbSet RequisitionComments{get;}
IDbSet命令{get;}
IDbSet OrderItems{get;}
IDbSet OrderFileUploads{get;}
IDbSet事务{get;}
IDbSet DispatchNotes{get;}
IDbSet DispatchItems{get;}
IDbSet LocationsInRolesForUser{get;}
}
SCSMContext:

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; }

}
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


}
公共类SCSMContext:System.Data.Entity.DbContext,IContext
{
#区域IContext成员
IDbSet_顺序;
公共秩序
{
得到
{
如果(_orders==null)
_orders=base.Set();
退货单;
}
}
//其他IContext定义。。。。。。
#端区
#区域IQueryableUnitOfWork成员
公共IDbSet CreateSet()
T:在哪里上课
{
返回base.Set();
}
公共无效附件(T项)
T:在哪里上课
{
//附加并设置为未更改
base.Entry(item).State=System.Data.EntityState.Unchanged;
}
修改公共作废设置(T项)
T:在哪里上课
{
//此操作还将附加对象状态管理器中的项
base.Entry(item).State=System.Data.EntityState.Modified;
}
公共无效ApplyCurrentValues(T原始值,T当前值)
T:在哪里上课
{
//如果未附加,请附加原始值并设置当前值
base.Entry(原始).CurrentValues.SetValues(当前);
}
公共无效佣金()
{
base.SaveChanges();
}
公共无效回滚更改()
{
//设置更改跟踪器中的所有实体
//作为“不变状态”
base.ChangeTracker.Entries()
托利斯先生()
.ForEach(entry=>entry.State=System.Data.EntityState.Unchanged);
}
公共IEnumerable ExecuteQuery(字符串sqlQuery,参数对象[]参数)
{
返回base.Database.SqlQuery(SqlQuery,参数);
}
public int ExecuteCommand(字符串sqlCommand,参数对象[]参数)
{
返回base.Database.SqlCommand(SqlCommand,参数);
}
#端区
}
另外,IQueryableUnitOfWork:(以防万一?)

公共接口IQueryableUnitOfWork:IUnitOfWork,ISql { /// ///返回一个IDbSet实例,用于访问上下文中给定类型的实体, ///ObjectStateManager和底层存储。 /// /// /// IDbSet CreateSet(),其中T:class; /// ///将此项目附加到“ObjectStateManager”中 /// ///实体的类型
///项目似乎我需要更多的澄清:为什么您要将调用容器的结果转换为
DoSomething
?您没有将上下文注入存储库。我猜存储库需要上下文才能正常工作。我不熟悉NLog,但如果它类似于Log4Net,您需要更多配置(如app.config中的专用部分或代码中的显式设置),以告知框架在何处记录(文件、数据库、事件日志等)以及要使用的记录器(平面文件记录器、滚动文件记录器等)而不是简单地调用LogManager.GetCurrentClassLogger

您希望缺少什么?您可以在应用程序的合成根目录(Main())中设置容器。您可以解析对象图的入口点(IDoSomething的实现),容器注入必要的依赖项,然后告诉根对象开始工作。就是这样。@SebastianWeber就是这样。即使我做了所有这些,我的存储库+unitOfWork对我的数据库也没有任何作用(无法获取或提交数据),我的记录器不会记录。很明显,我做得不对:\n您是否为记录器和上下文创建了配置文件?此文件是否复制到您的BIN文件夹?或者您是否在某个地方的代码中配置了它们?显然,它们是在代码中配置的。请参阅我的(有点大)编辑上面!你是对的,我不需要在那里强制转换任何内容。更改了它。是的,NLog有自己的NLog.config,其中说明了记录位置(目标)和记录内容(规则)。而且,我将研究不在Unity中注册IContext的问题;我一直在这样做,因为这是在这个项目中完成的方式。。也是的,存储库需要上下文才能正常工作。注意:我可以从MVC项目中记录和使用我的存储库(将它们注入到我的控制器中)没有问题!@seed_87如果记录器和存储库都被注入并通过
DoSomething
调用,那么我认为这是这两个的配置问题,而不是容器问题。