Dependencies waiting to be satisifed - asp.net-mvc-3

I'm trying to abstract some simple tasks for some very simple objects.
In my domain model, there are a number of different objects which basically serve as a way to tag (classify) a "Program." The Business Logic says a program can have as many of these as its wants, but no tags of the same type (e.g., "County") can have the same name, and you can't delete a tag while it has programs linked to it.
This is built on MVC3 with S#arp 2.0.
The domain model has an abstract base class NamedEntity : Entity which defines
public string Name { get; set; }
among other properties.
Specific types extend this class to add whatever makes them unique (if anything), such as Topic, which is a heirarchical structure and so has additional properties for that.
I wanted to create INamedEntityTasks<T> where T: NamedEntity and then have a base version of this for handling routine tasks like bool CheckForDuplicateName(string Name) which would run access its INamedEntityQueries<T> object and call T FindByName(string Name)
If a subclass needed to add more rules prior to delete (e.g. a topic with children can't be deleted), then it just overrides the virtual method from the base class.
Structure:
MyProject.Infrastructure has INamedEntityQueries<T> and NamedEntityQueries<T> as well as ITopicQueries : INamedEntityQueries<Topic> and TopicQueries: NamedEntityQueries<T>, ITopicQueries
MyProject.Domain.Contracts.Tasks has INamedEntityTasks<T> and ITopicTasks : INamedEntityTasks<Topic>
MyProject.Tasks has NamedEntityTasks<T> and TopicTasks: NamedEntityTasks<Topic>, ITopicTasks
My TopicsController won't run because of a missing dependency that I can't figure out.
The exact exception is
Can't create component
'MyProject.web.mvc.controllers.topicscontroller'
as it has dependencies to be
satisfied.
MyProject.web.mvc.controllers.topicscontroller
is waiting for the following
dependencies:
Services:
- MyProject.Infrastructure.Queries.ITopicQueries
which was not registered.
- MyProject.Domain.Contracts.Tasks.ITopicTasks
which was registered but is also
waiting for dependencies.
MyProject.Tasks.TopicTasks is waiting
for the following dependencies:
Services:
- MyProject.Infrastructure.Queries.INamedEntityQueries`1[[MyProject.Domain.Topic,
MyProject.Domain, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null]]
which was not registered.
I checked the container in ComponentRegistrar with a breakpoint and it shows 3 potentially misconfigured:
"MyProject.Tasks.NamedEntityTasks`1" NamedEntityTasks`1
"MyProject.Tasks.TopicTasks" ITopicTasks / TopicTasks
"MyProject.web.mvc.controllers.topicscontroller" TopicsController`TopicsController`
Any help would be appreciated.

You don't need the IFooTasks interface, just use an abstract base class, then IFooBarTasks and IFooBazTasks will be registered with Castle Windsor by the standard ComponentRegistrar in S#arp Architecture:
public abstract class Foo
{
public void Foo1();
public void Foo2();
}
public class FooBar : Foo
{
public void FooBar1();
}
public class FooBaz : Foo
{
public void FooBaz1();
}
public interface IFooTasks
{
void Foo1();
void Foo2();
}
public interface IFooBarTasks : IFooTasks
{
void FooBar1();
}
public interface IFooBazTasks : IFooTasks
{
void FooBaz1();
}
public abstract class FooTasks : IFooTasks
{
public void Foo1()
{
// Foo1 implementation
}
public void Foo2()
{
// Foo2 implementation
}
}
public class FooBarTasks : FooTasks, IFooBarTasks
{
public void FooBar1()
{
// FooBar1 implementation
}
}
public class FooBazTasks : FooTasks, IFooBazTasks
{
public void FooBaz1()
{
// FooBaz1 implementation
}
}

Related

AspnetBoilerplate modular: The entity type XXX is not part of the model for the current context

Sorry for my bad English, Could anyone help me with this error as below:
I have followed this tutorial to create a new module application (named Payment) on AspnetZero framework (named FastOne).
In the second DbContext, I change the default conn to my second database and add new entity name BankCode. After add-migration and update-database, everything works well. New database was created with 1 table name BankCode
I went to create a AppService in .Application module project as below:
public class BankCodeAppService : FastOneAppServiceBase, IBankCodeAppService
{
//from PaymentDbContext
private readonly IRepository<BankCode> _repository;
public BankCodeAppService(IRepository<BankCode> repository)
{
_repository = repository;
}
public ListResultDto<BankCodeDto> GetAllBankCodeDto()
{
try
{
var result = _repository.GetAll().ToList();
return new ListResultDto<BankCodeDto>(result.MapTo<List<BankCodeDto>>());
}
catch (Exception ex)
{
throw new NotImplementedException();
}
}
}
This is my PaymentDbContext
[DefaultDbContext]
[AutoRepositoryTypes(
typeof(IPaymentRepositoryBase<>),
typeof(IPaymentRepositoryBase<,>),
typeof(PaymentRepositoryBase<>),
typeof(PaymentRepositoryBase<,>)
)]
public class PaymentDbContext : FastOneDbContext
{
/* Define an IDbSet for each entity of the application */
public virtual IDbSet<BankCode.BankCode> BankCodes { get; set; }
//TODO: Define an IDbSet for your Entities...
public PaymentDbContext() : base("SecondConn") { }
public PaymentDbContext(string nameOrConnectionString) : base(nameOrConnectionString) { }
public PaymentDbContext(DbConnection connection) : base(connection) { }
}
The api was created successfully, but when I called to it, it returned the error as below:
The entity type BankCode is not part of the model for the current
context.
I tried to debug and realize that the repository is FastOneDbContext instead of PaymentDbContext : [Wrong repository when debugging][2]
I'm totally new with AspNetBoilerplate and module Zero. So could anyone please to help me. Thank
Update: This is my PaymentRepositoryBase
namespace FastOne.EntityFramework.Repositories
{
public class PaymentRepositoryBase<TEntity, TPrimaryKey> : FastOneRepositoryBase<TEntity, TPrimaryKey>
where TEntity : class, IEntity<TPrimaryKey>
{
public PaymentRepositoryBase(IDbContextProvider<PaymentDbContext> dbContextProvider) : base(dbContextProvider) { }
//do not add any method here, add to the class above (since this inherits it)
}
public abstract class PaymentRepositoryBase<TEntity> : PaymentRepositoryBase<TEntity, int>
where TEntity : class, IEntity<int>
{
public PaymentRepositoryBase(IDbContextProvider<PaymentDbContext> dbContextProvider) : base(dbContextProvider) { }
//do not add any method here, add to the class above (since this inherits it)
}
}
Update 3
Thank for your help Aaron, everything goes correctly, this is the newest error, I have searched some solutions but they didn't work. Please help
No component for supporting the service
FastOne.EntityFramework.PaymentDbContext was found
Update 4
I tried to add this method to PaymentDataModule:
public override void Initialize()
{
IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
}
It worked!, I can see _repository get correct context. but when i run, it raised this error:
System.Data.SqlClient.SqlException: Invalid object name
'dbo.BankCode'.
I realized that the connection was wrong. It was the connstring of the first context
Update 5: I found that I have 3 constructors in PaymentDbContext. So i removed these lines:
public PaymentDbContext() : base("LocalPaymentConn") { }
//public PaymentDbContext(string nameOrConnectionString) : base(nameOrConnectionString) { }
//public PaymentDbContext(DbConnection connection) : base(connection) { }
-->It received the correct connection string. So awesome!! Thanks Aaron and Tien for all your help. Thank you
You should inject IPaymentRepositoryBase as you have specified in AutoRepositoryTypes.
public class BankCodeAppService : FastOneAppServiceBase, IBankCodeAppService
{
private readonly IPaymentRepositoryBase<BankCode> _repository;
public BankCodeAppService(IPaymentRepositoryBase<BankCode> repository)
{
_repository = repository;
}
}
Update 1
ComponentActivator: could not instantiate FastOne.EntityFramework.Repositories.PaymentRepositoryBase`1‌​[[FastOne.BankCode.B‌​ankCode, FastOne.Payment.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]
Remove abstract keyword from the class declaration for PaymentRepositoryBase<TEntity>.
Update 2
Target does not implement interface FastOne.Domain.Repositories.IPaymentRepositoryBase`1[[FastOn‌​e.BankCode.BankCode, FastOne.Payment.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]\r\nParameter name: target
Make PaymentRepositoryBase implement IPaymentRepositoryBase.
public class PaymentRepositoryBase<TEntity> : PaymentRepositoryBase<TEntity, int>, IPaymentRepositoryBase<TEntity>
where TEntity : class, IEntity<int>
{
public PaymentRepositoryBase(IDbContextProvider<PaymentDbContext> dbContextProvider) : base(dbContextProvider) { }
}
You are using mutilple dbcontext in the app. So the second context must be inherit from AbpDbContext to ABP inject this correctly. See MultipleDbContextDemo example on https://github.com/aspnetboilerplate/aspnetboilerplate-samples.
Hope this will help you.

JavaEE CDI in Weld: Generic Events?

I have an idea for a specific event handling based on generics, but seems like Weld can't handle them. I asked google but couldn't find an alternative CDI extension for this.
Question: is there a CDI extension, that can handle event propagation of generic-typed events?
In the following the explicit problem I have.
I have three general events, EntityCreated, EntityChanged and EntityDeleted. The base class for them is defined like this:
public abstract class DatabaseEvent<TargetType> {
public TargetType target;
public DatabaseEvent(TargetType target) {
this.target = target;
}
}
The events then are simple inherited classes:
public class EntityCreatedEvent<TargetType> extends DatabaseEvent<TargetType> {
public EntityCreatedEvent(TargetType target) {
super(target);
}
}
I fire them like this:
public abstract class MyHome<EntityType> {
private EntityType entity;
#Inject
Event<EntityCreatedEvent<EntityType>> entityCreatedEvent;
public void fireCreatedEvent() {
EntityCreatedEvent<EntityType> payload = new EntityCreatedEvent<EntityType>(entity);
entityCreatedEvent.fire(payload);
}
}
I want to observe them like this:
public void handleProjectCreated(#Observes EntityCreatedEvent<Project> event) { ... }
When launching the server Weld tells me it can't handle generic-typed events. The CDI-way of doing things would be to use additional qualifiers instead of the generics to distiguish them, e.g.:
public void handleProjectCreated(#Observes #ProjectEvent EntityCreatedEvent event) { ... }
However, I fire the events from that MyHome base class, where I can't just fire with the #ProjectEvent: it might not be a project but another type.
My solution up to now is to skip that typing altogether and handle them like this:
public void handleProjectCreated(#Observes EntityCreatedEvent event) {
if(event.target instanceof Project) { ... }
}
This solution is okay, but not perfect.
I guess you can do this with dinamically binding qualifier members. This is what your code would look like:
public abstract class MyHome {
private EntityType entity;
#Inject
Event<EntityCreatedEvent> entityCreatedEvent;
public void fireCreatedEvent() {
entityCreatedEvent.select(getTypeBinding()).fire(new EntityCreatedEvent(entity));
}
private TypeBinding getTypeBinding() {
return new TypeBinding() {
public Class<? extends EntityType> value() {return entity.getClass();}
};
}
#Qualifier
#Target({ PARAMETER, FIELD })
#Retention(RUNTIME)
public #interface EntityTypeQualifier {
Class<? extends EntityType> value();
}
public abstract class TypeBinding extends AnnotationLiteral<EntityTypeQualifier> implements EntityTypeQualifier {}
//Observers
public void handleEntityType1Created(#Observes #EntityTypeQualifier(EntityType1.class) EntityCreatedEvent event) {}
public void handleEntityType2Created(#Observes #EntityTypeQualifier(EntityType2.class) EntityCreatedEvent event) {}
As this CDI issue points it is not possible to fire an without having the type of T at runtime.
But, if you have the type of T (i.e. you have an instance) you can use the Event as an Instance, and select the event to be fired using a dynamic type literal.

How to pass Data to different Views in MVVM Light?

I am kinda unclear on how to pass data to other views. I gathered there are 3 ways to do this but I not sure how to do 2 of them.
Send data through messenger(not sure if you can send objects otherwise I can see thing getting pretty messy if you have to send like 10 pieces of data or something like that along).
Somehow pass the data through the constructor of the new view model. I say "somehow" as I am unclear how to do that when using an IOC container(in this case the built in one).
Passing the data through a parameter. I seen a couple of tutorials that show you how to do navigation for the windows phone but none really talk about parameter passing. I am guessing this would still be an option.
From what I heard is that Option 1 is sort of the old way of doing it. Option 2 seems to be a newer way and better way to do it but I cannot find any examples on people showing how to do it.
I don't know how to do it because the Ioc should be creating the instance of the view so how do you pass in data into it when that data does not exist?
The two main ways I do this is:
1)Use the messenger:
Sender class:
public class TrafficLight
{
public string Color{get;set;}
public TimeSpand Duration{get;set;}
}
public class TrafficLightService
{
public void SendLight(TrafficLight light)
{
Messenger.Default.Send(light);
}
}
Receiver:
public class MyViewModel
{
public MyViewModel()
{
Messenger.Default.Register<TrafficLight>(DoSomethingWithTrafficLight);
}
private void DoSomethingWithTrafficLight(TrafficLight light)
{
}
}
What happens here is that the source object is using the Messenger as an event broker. Object A doesn't need to know about object B, they just both need to know about the messenger.
2)
Just use dependency injection:
public class TrafficLight
{
public string Color{get;set;}
public TimeSpand Duration{get;set;}
}
public class LightEventArgs:EventArgs
{
public LightEventArgs(TrafficLight light)
{
_light=light;
}
public TrafficLight Light{get{return _light;}}
}
public interface ITrafficLightService
{
void SendLight(TrafficLight light);
public event EventHandler<LightEventArgs> TrafficLightSet;
}
public class TrafficLightService
{
public void SendLight(TrafficLight light)
{
Messenger.Default.Send(light);
}
public event EventHandler<LightEventArgs> TrafficLightSet;
}
public class TrafficLightSenderViewModel
{
public TrafficLightSenderViewModel(ITrafficLightService trafficLightService)
{
_trafficLightService=trafficLightService;
_trafficLightService.Send(new TrafficLight{Color="Red"});
}
}
public class TrafficLightReceiverViewModel
{
public TrafficLightReceiverViewModel(ITrafficLightService trafficLightService)
{
_trafficLightService=trafficLightService;
_trafficLightService.TrafficLightSet+= TrafficLightNotification;
}
private void TrafficLightNotification(TrafficLightEventArgs args)
{
DoSomethingWithTheLight(args.Light);
}
}
public class ViewModelLocator
{
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
if (ViewModelBase.IsInDesignModeStatic)
{
SimpleIoc.Default.Register<ITrafficLightService, Design.TrafficLightService>();
}
else
{
SimpleIoc.Default.Register<ITrafficLightService, TrafficLightService>();
}
SimpleIoc.Default.Register<TrafficLightSenderViewModel>();
SimpleIoc.Default.Register<TrafficLightReceiverViewModel>();
}
public MainViewModel Sender
{
get { return SimpleIoc.Default.GetInstance<TrafficLightSenderViewModel>(); }
}
public MainViewModel Receiver
{
get { return SimpleIoc.Default.GetInstance<TrafficLightReceiverViewModel>(); }
}
}
This is a bigger example and more complex.
Lets walk through this step by step:
In MVVM Light we use the ViewModelLocator for 2 things: 1)To register all our viewmodels and services.
Provide a way to allow the View to get a viewmodel in XAML
When we try to resolve a ViewModel
SimpleIoc.Default.GetInstance<TrafficLightReceiverViewModel>();
SimpleIoc looks at whether the viewmodel has any dependencies. In our case we do, we need an ITrafficLightService for both our viewmodels. What happens is that SimpleIoc sees if it can resolve that class and, in the process, checks to see if ITrafficLightService has any dependencies that need resolving as well. If SimpleIoc can resolve the chain of dependencies required to instantiate your viewmodel it does so and then hands back a fully built object.

Windows Phone - Using generic class for PhoneApplicationPage

I have a Page which consist of AddPage.xaml and AddPage.xaml.cs. I want to create a generic class AddPage which extends from PhoneApplicationPage to outsource some repetitive code like Save or Cancel.
If I change the base class from PhoneApplicationPage to my new generic class, I get this error: Partial declarations of 'AddPage' must not specify different base classes.
To accomplish this you need to do the following.
First, create your base class
public class SaveCancelPhoneApplicationPage : PhoneApplicationPage
{
protected void Save() { ... }
protected void Cancel() { ... }
}
Then, your AddPage needs to be modified to inherit from the base class. The main places this is needed is within the code (AddPage.xaml.cs) AND within the xaml
Code:
public partial class AddPage : SaveCancelPhoneApplicationPage { ... }
Xaml:
<local:SaveCancelPhoneApplicationPage
x:Class="MyPhone.Namespace.AddPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyPhone.Namespace"
<!-- other xaml elements -->
</local:SaveCancelPhoneApplicationPage>
UPDATE: Info added based on comments
If you need to have generic like functionality and you must use the Page to do this (rather than a ViewModel) then you can still do this using generic methods
public abstract class SaveCancelPhoneApplicationPage : PhoneApplicationPage
{
protected override void OnNavigatedTo(blaa,blaa)
{
var obj = CreateMyObject();
obj.DoStuff();
}
// You should know what your objects are,
// don't make it usable by every phone dev out there
protected MyBaseObject MyObject { get; set; }
protected T GetMyObject<T>() where T : MyBaseObject
{
return MyObject as T;
}
}
public class AddPage : SaveCancelPhoneApplicationPage
{
public AddPage()
{
MyObject = new MyAddObject();
}
}
In order to outsource some functions you just declare some add class which does the common work. Having another page doesn't do that work.
public class Add
{
public bool SaveContent(string filename, string content)
{
....//some content
return true;
}
public string ViewContent(string filename)
{
string content="";
.....
return content;
}
}
Add this part of code where you thought it is redundant.
Add obj=new Add();
obj.SaveContent("myfile.txt","Hello.This is my content.");
string content("myfile.txt");
Tell me if this is what you intend or not.

How to set up an object with InternalsVisibleTo in an assembly to implement partial mocks with Rhino Mocks 3.6

Below, I have code for an object that I would like to test. It is in an assembly called Business and I have added the attributes in the AssemblyInfo.cs to make internals visible to the test and rhino mocks which are located in another assembly. When testing the GenerateReport method, I can not fake out the call to ValidateWorkingDirectory when it is "internal" (System.ApplicationException : Must set Working Directory before any method calls.). If I make ValidateWorkingDirectory public, the problem goes away. I thought InternalsVisibleTo would address this issue.
public class MyClass : IMyClass
{
private readonly IMyClassDataProvider _myClassDataProvider;
public virtual string WorkingDirectory { get; set; }
public MyClass(IMyClassDataProvider myClassDataProvider)
{
_myClassDataProvider = myClassDataProvider;
}
internal virtual void ValidateWorkingDirectory()
{
if (string.IsNullOrEmpty(WorkingDirectory))
{
throw new ApplicationException("Must set Working Directory before any method calls.");
}
}
public virtual void GenerateReport(vars)
{
ValidateWorkingDirectory();
InsertData(_myClassDataProvider.GetData(vars), "ReportName");
}
internal virtual void InsertData(DataSet analysis, string fileName)
{
DoSomeStuff();
}
private static void DoSomeStuff()
{
//Whatevs
}
}
//In AssmeblyInfo.cs
[assembly: InternalsVisibleTo("UnitTests.Business")]
[assembly: InternalsVisibleTo("Rhino.Mocks")]
[TestFixture]
public class MyClassTests : TestFixtureBase
{
private MockRepository _mocks;
private IMyClassDataProvider _myClassDataProvider;
private MyClass _myClass;
private var _vars;
[SetUp]
protected void Init()
{
_mocks = new MockRepository();
_myClassDataProvider = _mocks.StrictMock<IMyClassDataProvider >();
_myClass = _mocks.PartialMock<MyClass>(_myClassDataProvider);
_vars = "who cares";
}
[Test]
[ExpectedException(typeof(ApplicationException), ExpectedMessage = "Must set Working Directory before any method calls.")]
public virtual void ShouldThrowAnExceptionIfWorkingDirectoryNotSet()
{
Expect.Call(_myClass.WorkingDirectory).Return(Random.Get<bool>() ? null : string.Empty);
_mocks.ReplayAll();
_myClass.ValidateWorkingDirectory();
_mocks.VerifyAll();
}
[Test]
public virtual void ShouldGenerateReport()
{
DataSet dataSetToReturn = new DataSet();
using (_mocks.Ordered())
{
Expect.Call(() => _myClass.ValidateWorkingDirectory());
Expect.Call(_myClassDataProvider.GetData(vars)).Return(dataSetToReturn);
_myClass.InsertData(dataSetToReturn, "ReportName");
}
_mocks.ReplayAll();
_myClass.GenerateReport(vars);
_mocks.VerifyAll();
}
}
You need to expose your internal members to proxy assembly, not Rhino's assembly itself:
[assembly: InternalsVisibleTo ("DynamicProxyGenAssembly2")]
When a class is mocked, a new class is generated at run-time which is derived from the mocked class. This generated class resides in a separate "temporary" assembly which is called "DynamicProxyGenAssembly2". So, the InternalsVisibleTo attribute needs to be set on the target assembly to allow access to its internal members from the temporary assembly.
This happens to be common misunderstanding, for detailed information on how to use internals visible with Rhino, check this documentation page.

Resources