写在前面: 第一次配置时好好的,后来第二次改到MVC模式,把依赖注入写成字典的单例模式时,由于新建的ORM(数据库映射模型EF),怎么弄都不用,一直报错"No connection string named '**Context' could be found in the application config file"(配置文件中找不到数据库context连接)调试了两小天问题,终于想到了是没有把EF模型中appconfig中的数据库连接复制到项目webconfig中导致的!!!改过之后果然好了,豁然开朗!
中间也发现了一个小的点:调试的时候因为配置有问题,就改成不用配置直接写的方式:(如下)
UnityContainer container = new UnityContainer(); container.RegisterType<DbContext, JDContext>(); container.RegisterType<IBaseService, BaseService>(); container.RegisterType<IUserMenuService, UserMenuService>(); IBaseService baseService = container.Resolve<IBaseService>(); IUserMenuService userservice = container.Resolve<IUserMenuService>(); JD_User a = userservice.Set<JD_User>().FirstOrDefault();
然后就报错BaseService是抽象类 不能实例化。 后来发现 这句不需要写出来
IBaseService baseService = container.Resolve<IBaseService>();
因为 IUserMenuService 继承了 IBaseService 实现IUserMenuService的时候自然就把基类带出来了实现了。
困惑了一天半 终于解决了。
以下是DI工厂实现
namespace Common { public class DIFactory { private static object _syncHelper = new object(); private static Dictionary<string, IUnityContainer> _UnityContainerDic = new Dictionary<string, IUnityContainer>(); public static IUnityContainer GetContainer(string containerName = "JDContainer") { if (!_UnityContainerDic.ContainsKey(containerName)) { lock (_syncHelper) { if (!_UnityContainerDic.ContainsKey(containerName)) { IUnityContainer container = new UnityContainer(); ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap(); fileMap.ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "CfgFiles\Unity.Config.xml"); Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None); UnityConfigurationSection section = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName); section.Configure(container, containerName); _UnityContainerDic.Add(containerName, container); } } } return _UnityContainerDic[containerName]; } } }
以下是unity文件配置 (即上文代码中的 Unity.Config.xml )
<configuration> <configSections> <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/> </configSections> <unity> <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration"/> <containers> <container name="JDContainer"> <!--<register type="Interface.ITest, Interface" mapTo="Service.Test, Service" />--> <register type="System.Data.Entity.DbContext, EntityFramework" mapTo="EF.Model.JDContext, EF.Model"/> <register type="Interface.IBaseService, Interface" mapTo="Service.BaseService, Service" /> <register type="Interface.IUserMenuService, Interface" mapTo="Service.UserMenuService, Service" /> </container> <!--<container name="testContainer"> <register type="Interface.ITest, Interface" mapTo="Service.Test, Service" /> <register type="System.Data.Entity.DbContext, EntityFramework" mapTo="EF.yuncaidbEntities, EF"/> <register type="Interface.IBaseService, Interface" mapTo="Service.BaseService, Service" /> <register type="Interface.IUserService, Interface" mapTo="Service.UserService, Service" /> </container>--> </containers> </unity> </configuration>