AutoMapper IMappingEngine ConfigurationStore Initialize Not Happening - asp.net-mvc-4

AutoMapper Version Used : 3.3.10
[TestClass]
public class AppControllerTests
{
private IMappingEngine _mappingEngine = null;
private ConfigurationStore _configurationStore = null;
[TestInitialize]
public void SetUp()
{
_configurationStore = new ConfigurationStore(new TypeMapFactory(), MapperRegistry.Mappers);
_configurationStore.AddProfile(new AutoMapperProfile.AppProfile());
_mappingEngine = new MappingEngine(_configurationStore);
}
[TestMethod]
public void GetAppByAccountID()
{
// Error line
var mappingResult = _mappingEngine.Map<Category>(categoryList).AsQueryable();
}
}
public class AppProfile : Profile
{
protected override void Configure()
{
AutoMapperMappingConfigurations();
}
public void AutoMapperMappingConfigurations()
{
Mapper.CreateMap<DomainModels.Category, Category>().ReverseMap();
}
}
Exception:
An exception of type 'AutoMapper.AutoMapperMappingException'
occurred in AutoMapper.dll but was not handled in user code.
Suspect the
_configurationStore.AddProfile(new OOS.PresentationModelService.AutoMapperProfile.AppProfile());
is not able to create an istance of AppProfile if i write the manual mapping it's working as expected.
_configurationStore.CreateMap<Category, Category>().ReverseMap();

Related

Xamarin MVVM push user data to viewmodel

like the title says I want to give through the user information to my viewmodel, but the problem is that the viewmodel is registered as a dependency and I am binding its content to the xaml page itself. How do I send the user information to the viewmodel itself?
Thank you!
Xaml.cs part:
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class Calendar : ContentPage
{
public Calendar(User user)
{
InitializeComponent();
FileImageSource image = new FileImageSource
{
File = "calendar.png"
};
Icon = image;// push user information to the ICalendarViewModel
BindingContext = AppContainer.Container.Resolve<ICalendarViewModel>();
}
}
Interface:
public interface ICalendarViewModel : INotifyPropertyChanged
{
}
Bootstrap part registering dependencies:
public class Bootstrap
{
public IContainer CreateContainer()
{
var containerBuilder = new ContainerBuilder();
RegisterDependencies(containerBuilder);
return containerBuilder.Build();
}
protected virtual void RegisterDependencies(ContainerBuilder builder)
{
builder.RegisterType<CalendarViewModel>()
.As<ICalendarViewModel>()
.SingleInstance();
}
}
CalendarViewModel: I do not know if this will help
public class CalendarViewModel : ViewModelBase, ICalendarViewModel
{
public event PropertyChangedEventHandler PropertyChanged;
public string ErrorMessage { get; set; }
private CourseInformation _information;
private ICourseInformationRepository _repository;
public CalendarViewModel()
{
_repository = new CourseInformationRepository();
LoadData();
}
private ObservableCollection<CourseInformation> _courses;
public ObservableCollection<CourseInformation> Courses
{
get
{
return _courses;
}
set
{
_courses = value;
RaisePropertyChanged(nameof(Courses));
}
}
private void LoadData()
{
try
{
ObservableCollection<CourseInformation> CourseList = new ObservableCollection<CourseInformation>(_repository.GetAllCourseInformation());
Courses = new ObservableCollection<CourseInformation>();
DateTime date;
foreach (var course in CourseList)
{
string [] cour = course.Date.Split('/');
cour[2] = "20" + cour[2];
date = new DateTime(Convert.ToInt32(cour[2]), Convert.ToInt32(cour[1]), Convert.ToInt32(cour[0]));
if (date == DateTime.Now)//TESTING WITH TEST DATE, datetime.now
{
if (course.FromTime.Length < 4)
{
course.FromTime = "0" + course.FromTime;
}
if (course.UntilTime.Length < 4)
{
course.UntilTime = "0" + course.UntilTime;
}
course.FromTime = course.FromTime.Insert(2, ":");
course.UntilTime = course.UntilTime.Insert(2, ":");
Courses.Add(course);
}
}
}
catch (ServerUnavailableException e)
{
ErrorMessage = "Server is niet beschikbaar, ophalen van kalender is niet mogelijk.";
}
}
private void RaisePropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Bootstrap binding in app.xaml.cs:
public partial class App : Application
{
public App()
{
InitializeComponent();
AppContainer.Container = new Bootstrap().CreateContainer();
MainPage = new LoginView();
}
protected override void OnStart()
{
// Handle when your app starts
}
protected override void OnSleep()
{
// Handle when your app sleeps
}
protected override void OnResume()
{
// Handle when your app resumes
}
}
I wanted to comment (not enough reputation) on #LeRoy, use a framework. I would recommend FreshMVVM and you can pass objects into the ViewModel and even pass in Services. It makes it all nice and clean, and it just works.
Should not your CalendarViewModel viewModel contain BindableBase ?
public class CalendarViewModel : BindableBase, ViewModelBase, ICalendarViewModel
what framework are you using? prism, freshmvvm.
Your View and Viewmodel is normally automatically handled by the framework, all you need to do is register your page.
Container.RegisterTypeForNavigation<Views.CalendarPage>();

Error activating service - Ninject

I am getting the following error whenever I try to inject one of my service's dependency into the MVC controller:
Error activating IFeedService No matching bindings are available, and the type is not self-bindable.
Activation path:
2) Injection of dependency IFeedService into parameter svc of constructor of type FeedController
1) Request for FeedController
Suggestions:
1) Ensure that you have defined a binding for IFeedService.
2) If the binding was defined in a module, ensure that the module has been loaded into the kernel.
3) Ensure you have not accidentally created more than one kernel.
4) If you are using constructor arguments, ensure that the parameter name matches the constructors parameter name.
5) If you are using automatic module loading, ensure the search path and filters are correct.
======================================================================
Here's how my code looks like:
ObjectFactory.cs
private static void RegisterServices(IKernel kernel)
{
// Contexts
kernel.Bind<IEntityObjectContext>().To<Entities>();
kernel.Bind<IAzureObjectContext>().To<AzureTableObjectContext>();
// Repositories
kernel.Bind<IEFRepository>().To<EFRepository>();
kernel.Bind<IAzureRepository>().To<AzureRepository>();
// Services
kernel.Bind<IFeedService>().To<FeedService>();
}
IEFRepository.cs
public interface IEFRepository : IDisposable
{
void SetContext(IEntityObjectContext context);
IQueryable<T> GetAll<T>() where T : class;
}
EFRepository.cs
public class EFRepository : IEFRepository
{
internal IEntityObjectContext context;
private Dictionary<Type, object> objectSets;
public EFRepository(IEntityObjectContext context)
{
this.context = context;
objectSets = new Dictionary<Type, object>();
}
public void SetContext(IEntityObjectContext context)
{
this.context = context;
}
}
IFeedService.cs
public interface IFeedService : IDisposable
{
IQueryable<FeedItem> GetPosts();
}
FeedService.cs
public class FeedService : IFeedService
{
private IEntityObjectContext _context;
private readonly IEFRepository _repo;
public FeedService(IEntityObjectContext context,
IEFRepository repo)
{
_context = context;
_repo = repo;
_repo.SetContext(_context);
}
public IQueryable<FeedItem> GetPosts()
{
using (_repo)
{
return _repo.GetAll<FeedItem>().Take(10);
}
}
}
FeedController.cs
public class FeedController : Controller
{
private readonly IFeedService _svc;
public FeedController(IFeedService svc)
{
_svc = svc;
}
}
As you can see, there are some nested dependency there in action. Not sure though, what needs to be added/removed for this bit to work.
Note: The error is thrown whenever I request the Feed/FetchFeed path. I also tried to comment out the FeedService's constructor portion to see if the nested dependencies are creating any problem, but again same error was thrown.
EDIT 1:
Rest of the code for the ObjectFactory.cs
class ObjectFactory
{
static ObjectFactory()
{
RegisterServices(kernel);
}
static IKernel kernel = new StandardKernel();
public static T GetInstance<T>()
{
return kernel.Get<T>();
}
private static void RegisterServices(IKernel kernel)
{
//...
}
}
EDIT 2:
I even tried to write a fairly basic service, but still the same error. Here's what I tried with:
public interface ITest
{
void CheckItOut();
}
public class Test : ITest
{
public void CheckItOut()
{
}
}
ObjectFactory.cs
kernel.Bind<ITest>().To<Test>();

Injecting Dependency into Web API Controller

I want to inject unity container into WebController.
I have UnityDependencyResolver:
public class UnityDependencyResolver : IDependencyResolver
{
readonly IUnityContainer _container;
public UnityDependencyResolver(IUnityContainer container)
{
this._container = container;
}
public object GetService(Type serviceType)
{
try
{
return _container.Resolve(serviceType);
}
catch
{
return null;
}
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return _container.ResolveAll(serviceType);
}
catch
{
return new List<object>();
}
}
public void Dispose()
{
_container.Dispose();
}
}
Then, in my Global.asax I add the following line:
var container = new UnityContainer();
container.RegisterType<IService, Service>
(new PerThreadLifetimeManager()).RegisterType<IDALContext, DALContext>();
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
Then, If I use the following in a Web Controller:
private IService _service;
public HomeController(IService srv)
{
_service = srv;
}
It works fine.
But I want to inject it into WebAPI Controller, so if I do it the same way:
private IService _service;
public ValuesController(IService srv)
{
_service = srv;
}
It does not work, it says that constructor is not defined.
Ok, I create one more constructor:
public ValuesController(){}
And in this case it uses only this constructor and never the one where I should inject unity container.
Please advise.
Add this in your WebApiConfig:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Routes and other stuff here...
var container = IocContainer.Instance; // Or any other way to fetch your container.
config.DependencyResolver = new UnityDependencyResolver(container);
}
}
And if you want the same container you can keep it in a static variable, like so:
public static class IocContainer
{
private static readonly Lazy<IUnityContainer> Container = new Lazy<IUnityContainer>(() =>
{
var container = new UnityContainer();
return container;
});
public static IUnityContainer Instance
{
get { return Container.Value; }
}
}
More info can be found here:
http://www.asp.net/web-api/overview/advanced/dependency-injection
On a sidenote, I can also recommend the nuget-package Unity.Mvc. It adds a UnityWebActivator and support for PerRequestLifetimeManager.
https://www.nuget.org/packages/Unity.Mvc/

Ninject issue with contextual binding and Lazy<T>

Ninject doesn't seem to correctly use WhenInjectedInto contstraint while also using Lazy<T>. Check the following example. The OnLandAttack and the OnLandAttackLazy should each be using the Samurai instance. But the Lazy<T> version ends up with the SpecialNinja instance. I'm guessing it's because it's not actually initialized in the contructor? But the type should still be correctly registered I would think. Am I missing something? FYI, this is using Ninject 3.2.2 and the Ninject.Extensions.Factory extension 3.2.1
class Program
{
static void Main(string[] args)
{
var kernel = new StandardKernel();
kernel.Load(new WarriorModule());
var amphibious = kernel.Get<IAttack>("amphibious");
amphibious.Execute();
var onLand = kernel.Get<IAttack>("onLand");
onLand.Execute();
var onLandLazy = kernel.Get<IAttack>("onLandLazy");
onLandLazy.Execute();
Console.ReadKey();
}
}
public class WarriorModule : NinjectModule
{
public override void Load()
{
Bind<IWarrior>().To<Samurai>().WhenInjectedInto<OnLandAttack>();
Bind<IWarrior>().To<Samurai>().WhenInjectedInto<OnLandAttackLazy>();
Bind<IWarrior>().To<SpecialNinja>(); // <-- for everything else
Bind<IAttack>().To<AmphibiousAttack>().Named("amphibious");
Bind<IAttack>().To<OnLandAttack>().Named("onLand");
Bind<IAttack>().To<OnLandAttackLazy>().Named("onLandLazy");
}
}
public interface IWarrior
{
void Attack();
}
public class Samurai : IWarrior
{
public void Attack()
{
Console.WriteLine("\tSamurai Attack");
}
}
public class SpecialNinja : IWarrior
{
public void Attack()
{
Console.WriteLine("\tSpecial Ninja Attack");
}
}
public interface IAttack
{
void Execute();
}
public class OnLandAttack : IAttack
{
private readonly IWarrior warrior;
public OnLandAttack(IWarrior warrior)
{
this.warrior = warrior;
}
public void Execute()
{
Console.WriteLine("Begin OnLand attack");
this.warrior.Attack();
}
}
public class OnLandAttackLazy : IAttack
{
private readonly Lazy<IWarrior> warrior;
public OnLandAttackLazy(Lazy<IWarrior> warrior)
{
this.warrior = warrior;
}
public void Execute()
{
Console.WriteLine("Begin OnLandLazy attack");
this.warrior.Value.Attack();
}
}
public class AmphibiousAttack : IAttack
{
private readonly IWarrior warrior;
public AmphibiousAttack(IWarrior warrior)
{
this.warrior = warrior;
}
public void Execute()
{
Console.WriteLine("Begin Amphibious attack");
this.warrior.Attack();
}
}

Changing default object scope with Ninject 2.2

Is it possible to change the default object scope in Ninject 2.2? If so, how is it done?
As far as I can tell you could override AddBinding() on the BindingRoot (StandardKernel or NinjectModule) and modify the ScopeCallback property on the binding object.
public class CustomScopeKernel : StandardKernel
{
public CustomScopeKernel(params INinjectModule[] modules)
: base(modules)
{
}
public CustomScopeKernel(
INinjectSettings settings, params INinjectModule[] modules)
: base(settings, modules)
{
}
public override void AddBinding(IBinding binding)
{
// Set whatever scope you would like to have as the default.
binding.ScopeCallback = StandardScopeCallbacks.Singleton;
base.AddBinding(binding);
}
}
This test should now pass (using xUnit.net)
public class DefaultScopedService { }
[Fact]
public void Should_be_able_to_change_default_scope_by_overriding_add_binding()
{
var kernel = new CustomScopeKernel();
kernel.Bind<DefaultScopedService>().ToSelf();
var binding = kernel.GetBindings(typeof(DefaultScopedService)).First();
binding.ScopeCallback.ShouldBe(StandardScopeCallbacks.Singleton);
}
The CustomScopeKernel will also work with Ninject modules.
public class ServiceModule : NinjectModule
{
public override void Load()
{
Bind<DefaultScopedService>().ToSelf();
}
}
[Fact]
public void Should_be_able_to_change_default_scope_for_modules()
{
var module = new ServiceModule();
var kernel = new CustomScopeKernel(module);
var binding = kernel.GetBindings(typeof(DefaultScopedService)).First();
binding.ScopeCallback.ShouldBe(StandardScopeCallbacks.Singleton);
}