我是设计模式和依赖注入的新手。我用这个教程来实现我的项目。
Solution implementing the above tutorial design pattern and dependency injection with IOC
我有两个API控制器:SongController和PlaylistController 根据教程,我已经实施到第Resolve-dependency-injection章
当我运行我的应用程序时,我的两个webapis 1)songcontroller中的http://localhost:49544/api/song与解析器一起正常工作 2)http://localhost:49544/api/playlist/8a79e096-052b-4057-9683-7a7443aa305a返回错误以及以下消息
数据库表中的{ “message”:“发生错误。”, “exceptionMessage”:“尝试创建'PlayListController'类型的控制器时发生错误。确保控制器具有无参数的公共构造函数。”, “exceptionType”:“System.InvalidOperationException”, “stackTrace”:“在System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage请求,HttpControllerDescriptor controllerDescriptor,类型controllerType)\ r \ n在System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)\ r \ n在System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()“, “innerException”:{ “message”:“发生错误。”, “exceptionMessage”:“依赖项的解析失败,类型='MusicCloudWebApi.Controllers.API.PlayListController',name ='(none)'。\ n发生异常时:解析时。\ nException是:InvalidOperationException - 当前类型,MusicCloud .Services.IPlayListServices,是一个无法构造的接口。你是否缺少类型映射?\ n ---------------------------- ------------------- \ n在异常时,容器是:\ r \ n解析MusicCloudWebApi.Controllers.API.PlayListController,(无)\ r \ n解析构造函数MusicCloudWebApi.Controllers.API.PlayListController(MusicCloud.Services.IPlayListServices playListServices)的参数'playListServices'\ r \ n解析MusicCloud.Services.IPlayListServices,(none)\ r \ n“, “exceptionType”:“Unity.Exceptions.ResolutionFailedException”, “stackTrace”:“Unity.UnityContainer.BuildUp(Type typeToBuild,Object existing,String name,ResolverOverride [] resolverOverrides)\ r \ n在Unity.UnityContainer.Resolve(Type type,String name,ResolverOverride [] resolverOverrides)\ r \ n \ n在Unity.Web.Http.Dispatcher.DefaultHttpControllerActivator的Unity.UnityContainerExtensions.Resolve(IUnityContainer容器,Type t,ResolverOverride []覆盖)\ r \ n在Unity.WebApi.UnityDependencyScope.GetService(类型serviceType)\ r \ n中\ n \ n .GetInstanceOrActivator(HttpRequestMessage请求,类型controllerType,Func
1& activator)\r\n at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)", "innerException": { "message": "An error has occurred.", "exceptionMessage": "The current type, MusicCloud.Services.IPlayListServices, is an interface and cannot be constructed. Are you missing a type mapping?", "exceptionType": "System.InvalidOperationException", "stackTrace": " at Unity.ObjectBuilder.BuildPlan.DynamicMethod.DynamicMethodConstructorStrategy.ThrowForAttemptingToConstructInterface(IBuilderContext context)\r\n at lambda_method(Closure , IBuilderContext )\r\n at Unity.ObjectBuilder.BuildPlan.DynamicMethod.DynamicBuildPlanGenerationContext.<>c__DisplayClass16_0.<GetBuildMethod>b__0(IBuilderContext context)\r\n at Unity.ObjectBuilder.BuildPlan.DynamicMethod.DynamicMethodBuildPlan.BuildUp(IBuilderContext context)\r\n at Unity.ObjectBuilder.Strategies.BuildPlanStrategy.PreBuildUp(IBuilderContext context)\r\n at Unity.Container.StrategyChain.BuildUp(IBuilderContext builderContext)\r\n at Unity.Policy.BuildPlanPolicyExtensions.ExecuteBuildUp(IBuildPlanPolicy policy, IBuilderContext context)\r\n at Unity.ObjectBuilder.BuilderContext.NewBuildUp(NamedTypeBuildKey newBuildKey, Action
1 childCustomizationBlock)\ r \ n在Unity.ResolverPolicy.NamedTypeDependencyResolverPolicy.Resolve(IBuilderContext context)\ r \ n在lambda_method(Closure,IBuilderContext)\ r \ n at Unity.ObjectBuilder.BuildPlan.DynamicMethod.DynamicBuildPlanGenerationContext。&lt;&gt; c__DisplayClass16_0.b__0(IBuilderContext context)\ r \ n在Unity.ObjectBuilder.BuildPlan.DynamicMethod.DynamicMethodBuildPlan.BuildUp(IBuilderContext context)\ r \ n Unity.ObjectBuilder.Strategies.BuildPrateStrategy.PreBuildUp(IBuilderContext context)\ r \ n在Unity.Container.StrategyChain.BuildUp(IBuilderContext builderContext)\ r \ n在Unity.Policy.BuildPlanPolicyExtensions.ExecuteBuildUp(IBuildPlanPolicy policy,IBuilderContext context) \ r \ n在Unity.UnityContainer.BuildUp(类型typeToBuild,Object existing,String name,ResolverOverride [] resolverOverrides)“ } } }
userId的类型为nvarchar(128)
我还没有实现身份验证,但是将表中的值硬编码为webapi的参数。
错误有什么问题?
Resolver project's solution explorer
Resolver项目具有以下接口和类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Resolver
{
public interface IComponent
{
void SetUp(IRegisterComponent registerComponent);
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition.Primitives;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Web;
using Unity;
using Unity.Lifetime;
namespace Resolver
{
public static class ComponentLoader
{
public static void LoadContainer(IUnityContainer container, string path, string pattern)
{
var dirCat = new DirectoryCatalog(path, pattern);
var importDef = BuildImportDefinition();
try
{
using (var aggregateCatalog = new AggregateCatalog())
{
aggregateCatalog.Catalogs.Add(dirCat);
using (var componsitionContainer = new CompositionContainer(aggregateCatalog))
{
IEnumerable<Export> exports = componsitionContainer.GetExports(importDef);
IEnumerable<IComponent> modules =
exports.Select(export => export.Value as IComponent).Where(m => m != null);
var registerComponent = new RegisterComponent(container);
foreach (IComponent module in modules)
{
module.SetUp(registerComponent);
}
}
}
}
catch (ReflectionTypeLoadException typeLoadException)
{
var builder = new StringBuilder();
foreach (Exception loaderException in typeLoadException.LoaderExceptions)
{
builder.AppendFormat("{0}\n", loaderException.Message);
}
throw new TypeLoadException(builder.ToString(), typeLoadException);
}
}
private static ImportDefinition BuildImportDefinition()
{
return new ImportDefinition(
def => true, typeof(IComponent).FullName, ImportCardinality.ZeroOrMore, false, false);
}
}
internal class RegisterComponent : IRegisterComponent
{
private readonly IUnityContainer _container;
public RegisterComponent(IUnityContainer container)
{
this._container = container;
//Register interception behaviour if any
}
public void RegisterType<TFrom, TTo>(bool withInterception = false) where TTo : TFrom
{
if (withInterception)
{
//register with interception
}
else
{
this._container.RegisterType<TFrom, TTo>();
}
}
public void RegisterTypeWithControlledLifeTime<TFrom, TTo>(bool withInterception = false) where TTo : TFrom
{
this._container.RegisterType<TFrom, TTo>(new ContainerControlledLifetimeManager());
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Resolver
{
/// <summary>
/// Responsible for registering types in unity configuration by implementing IComponent
/// </summary>
public interface IRegisterComponent
{
/// <summary>
/// Register type method
/// </summary>
/// <typeparam name="TFrom"></typeparam>
/// <typeparam name="TTo"></typeparam>
/// <param name="withInterception"></param>
void RegisterType<TFrom, TTo>(bool withInterception = false) where TTo : TFrom;
/// <summary>
/// Register type with container controlled life time manager
/// </summary>
/// <typeparam name="TFrom"></typeparam>
/// <typeparam name="TTo"></typeparam>
/// <param name="withInterception"></param>
void RegisterTypeWithControlledLifeTime<TFrom, TTo>(bool withInterception = false) where TTo : TFrom;
}
}
在MusicWebAPI项目解决方案中,在global.asax(UnityConfig.RegisterComponents();)调用以下类UnityConfig
using MusicCloud.Model;
using MusicCloud.Services;
using Resolver;
using System.Web.Http;
using System.Web.Mvc;
using Unity;
using Unity.Lifetime;
using Unity.WebApi;
namespace MusicCloudWebApi
{
public static class UnityConfig
{
public static void RegisterComponents()
{
var container = BuildUnityContainer();
// System.Web.Mvc.DependencyResolver.SetResolver(new UnityDependencyResolver(container));
System.Web.Mvc.DependencyResolver.SetResolver(new Unity.Mvc5.UnityDependencyResolver(container));
// register dependency resolver for WebAPI RC
GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container);
// Create the depenedency resolver.
//var resolver = new AutofacWebApiDependencyResolver(container);
// Configure Web API with the dependency resolver.
//GlobalConfiguration.Configuration.DependencyResolver = resolver;
}
private static IUnityContainer BuildUnityContainer()
{
var container = new UnityContainer();
// register all your components with the container here
// it is NOT necessary to register your controllers
// e.g. container.RegisterType<ITestService, TestService>();
// container.RegisterType<IProductServices, ProductServices>().RegisterType<UnitOfWork>(new HierarchicalLifetimeManager());
RegisterTypes(container);
return container;
}
public static void RegisterTypes(IUnityContainer container)
{
//Component initialization via MEFE:\Susana\Portfolio\MusicCloud\MusicCloud\MusicCloudWebApi\bin\MusicCloudWebApi.dll
ComponentLoader.LoadContainer(container, ".\\bin", "MusicCloudWebApi.dll");
ComponentLoader.LoadContainer(container, ".\\bin", "MusicCloud.Services.dll");
// container.Register<DashboardDbContext>(
// new InjectionFactory(c => new DashboardDbContext()));
}
}
internal class AutofacWebApiDependencyResolver
{
private IUnityContainer container;
public AutofacWebApiDependencyResolver(IUnityContainer container)
{
this.container = container;
}
}
}
在MusicCloud.Model中,我有一个类名DependencyResolver
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel.Composition;
using Resolver;
using MusicCloud.Repository;
using System.Data.Entity;
using MusicCloud.Model;
namespace MusicCloud.Model
{
/// <summary>
/// a) Export in System.ComponentModel.Composition
/// b)IComponent in Resolver in Resolver Project
/// </summary>
[Export(typeof(IComponent))]
public class DependencyResolver : IComponent
{
public void SetUp(IRegisterComponent registerComponent)
{
registerComponent.RegisterType<IUnitOfWork, UnitOfWork>();
}
}
}
playlistcontroller(API)
[System.Web.Http.HttpGet]
//// GET api/playlist/abc
public HttpResponseMessage GetPlayLists(string userId)
{
userId = "8a79e096-052b-4057-9683-7a7443aa305a";
var playLists = _playListServices.GetAllPlayLists(userId);
if (playLists != null)
{
var playListEntities = playLists as List<PlayListEntity> ?? playLists.ToList();
if (playListEntities.Any())
return Request.CreateResponse(HttpStatusCode.OK, playListEntities);
}
return Request.CreateErrorResponse(HttpStatusCode.NotFound, "PlayLists not found");
}
在MusicCloud.Services中,我有一个实现PlayListServices的接口IPlayListServices
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MusicCloud.Entities;
using MusicCloud.Model;
using AutoMapper;
using MusicCloud.Model.EFModel;
using System.Transactions;
namespace MusicCloud.Services
{
public class PlayListServices : IPlayListServices
{
private readonly UnitOfWork _unitOfWork;
/// <summary>
/// Public constructor.
/// </summary>
//public PlayListServices()
//{
// _unitOfWork = new UnitOfWork();
//}
public PlayListServices(UnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
/// <summary>
/// Fetches playList details by id
/// </summary>
/// <param name="playListId"></param>
/// <returns></returns>
public PlayListEntity GetPlayListById(int playListId)
{
var playList = _unitOfWork.PlayListRepository.GetByID(playListId);
if (playList != null)
{
// Mapper.CreateMap<Song, SongEntity>();
Mapper.Initialize(cfg =>
{
cfg.CreateMap<PlayList, PlayListEntity>();
//Mapper.Map<Song, SongEntity>();
});
var playListModel = Mapper.Map<PlayList, PlayListEntity>(playList);
return playListModel;
}
return null;
}
/// <summary>
/// Fetches all the songs.
/// </summary>
/// <returns></returns>
public IEnumerable<PlayListEntity> GetAllPlayLists(string userId)
// public PlayListEntity GetAllPlayLists(int userId)
{
var playLists = _unitOfWork.PlayListRepository
.GetAllSongs(x =>
x.PlayListSongs.Select(report => report.UserId==userId)).ToList();
if (playLists.Any())
{
Mapper.Initialize(cfg =>
{
cfg.CreateMap<PlayList, PlayListEntity>();
});
var playListsModel = Mapper.Map<List<PlayList>, List<PlayListEntity>>(playLists);
return playListsModel;
}
return null;
}
/// <summary>
/// Creates a product
/// </summary>
/// <param name="productEntity"></param>
/// <returns></returns>
public int CreatePlaylist(PlayListEntity playListEntity)
{
///remove
var userId = "1";
using (var scope = new TransactionScope())
{
var playList = new PlayList
{
Name = playListEntity.Name,
CreatedDate= playListEntity.CreatedDate,
ModifiedDate=playListEntity.ModifiedDate
};
_unitOfWork.PlayListRepository.Insert(playList);
_unitOfWork.Save();
scope.Complete();
return playList.Id;
}
}
}
}
答案 0 :(得分:0)
@ NightOwl888感谢依赖修复程序的提示。我找到了导致这个问题的原因。我错过了在dependencyresolver.cs中注册IplaylistServices
registerComponent.RegisterType<IPlayListServices, PlayListServices>();