Class cannot be used as type parameter in the generic type or method, there is no implicit reference conversion - asp.net-mvc

I am building (attempting to build) generic Repository, Task, and Controllers for my MVC 4 project and using it to learn generics and interfaces. I've gotten pretty far, but stuck on this error. CustomerContactsListViewModel does inherit from IViewModelList, which is why I am perplexed.
Error:
The type 'OTIS.AppServ.OrderMgmt.ViewModels.CustomerContactsListViewModel' cannot be used as type parameter 'TViewModelList' in the generic type or method 'OTIS.AppServ.BaseAppServGrid<TRepository,TViewModelSingle,TViewModelList>'. There is no implicit reference conversion from 'OTIS.AppServ.OrderMgmt.ViewModels.CustomerContactsListViewModel' to 'OTIS.AppServ.IViewModelList<OTIS.domain.OrderMgmt.Customer,OTIS.AppServ.OrderMgmt.ViewModels.CustomerContactsListViewModel>'.
The interface:
public interface IViewModelList<TClass, TViewModelList>
{
IEnumerable<TClass> ConvertViewModelToClass(IEnumerable<TViewModelList> entityList);
IEnumerable<TViewModelList> ConvertClassToViewModel(IEnumerable<TClass> entityList);
}
The View Model that inherits the Interface:
public class CustomerContactsListViewModel : IViewModelList<CustomerContact, CustomerContactsListViewModel>, IEntity
Generic Task (Application Services) class being inherited:
public class BaseAppServGrid<TRepository, TViewModelSingle, TViewModelList> : BaseAppServ<TRepository, TViewModelSingle>
where TRepository : class, IEntity, IAuditStamps, new()
where TViewModelSingle : class, IViewModelSingle<TRepository, TViewModelSingle>, new()
where TViewModelList : class, IEntity, IViewModelList<TRepository, TViewModelList>, new()
The specific Task/App services class trying to inherit the Base, which throws the error:
public class ManageCustomersAppServ : BaseAppServGrid<Customer, CustomerViewModel, CustomerContactsListViewModel>

In the CustomerContactsListViewModel you have implemented the first parameter of IViewModelList to be of type CustomerContact.
However, the class ManageCustomersAppServ has been declared with type Customer.
So
IViewModelList<Customer, CustomerContactsListViewModel>
is not assignable to
IViewModelList<CustomerContact, CustomerContactsListViewModel>
You need to either:
Change BaseAppServGrid to take another generic parameter like so:
public class BaseAppServGrid<TModel, TRepository, TViewModelSingle, TViewModelList> :
BaseAppServ<TRepository, TViewModelSingle>
where TRepository : class, IEntity, IAuditStamps, new()
where TViewModelSingle : class, IViewModelSingle<TRepository, TViewModelSingle>, new()
where TViewModelList : class, IEntity, IViewModelList<TModel, TViewModelList>, new()
public class ManageCustomersAppServ : BaseAppServGrid<CustomerContact, Customer, CustomerViewModel, CustomerContactsListViewModel>
Review whether Customer and CustomerContact can derive from some IRepository interface/class, if that was your intention when you passed Customer to a generic param called "TRepository".

Related

What is the purpose of the getter methods in Components in Dagger 2?

I am trying to understand Components in Dagger 2. Here is an example:
#Component(modules = { MyModule.class })
public interface MyComponent {
void inject(InjectionSite injectionSite);
Foo foo();
Bar bar();
}
I understand what the void inject() methods do. But I don't understand what the other Foo foo() getter methods do. What is the purpose of these other methods?
Usage in dependent components
In the context of a hierarchy of dependent components, such as in this example, provision methods such as Foo foo() are for exposing bindings to a dependent component. "Expose" means "make available" or even "publish". Note that the name of the method itself is actually irrelevant. Some programmers choose to name these methods Foo exposeFoo() to make the method name reflect its purpose.
Explanation:
When you write a component in Dagger 2, you group together modules containing #Provides methods. These #Provides methods can be thought of as "bindings" in that they associate an abstraction (e.g., a type) with a concrete way of resolving that type. With that in mind, the Foo foo() methods make the Component able to expose its binding for Foo to dependent components.
Example:
Let's say Foo is an application Singleton and we want to use it as a dependency for instances of DependsOnFoo but inside a component with narrower scope. If we write a naive #Provides method inside one of the modules of MyDependentComponent then we will get a new instance. Instead, we can write this:
#PerFragment
#Component(dependencies = {MyComponent.class }
modules = { MyDependentModule.class })
public class MyDependentComponent {
void inject(MyFragment frag);
}
And the module:
#Module
public class MyDepedentModule {
#Provides
#PerFragment
DependsOnFoo dependsOnFoo(Foo foo) {
return new DependsOnFoo(foo);
}
}
Assume also that the injection site for DependentComponent contains DependsOnFoo:
public class MyFragment extends Fragment {
#Inject DependsOnFoo dependsOnFoo
}
Note that MyDependentComponent only knows about the module MyDependentModule. Through that module, it knows it can provide DependsOnFoo using an instance of Foo, but it doesn't know how to provide Foo by itself. This happens despite MyDependentComponent being a dependent component of MyComponent. The Foo foo() method in MyComponent allows the dependent component MyDependentComponent to use MyComponent's binding for Foo to inject DependsOnFoo. Without this Foo foo() method, the compilation will fail.
Usage to resolve a binding
Let's say we would like to obtain instances of Foo without having to call inject(this). The Foo foo() method inside the component will allow this much the same way you can call getInstance() with Guice's Injector or Castle Windsor's Resolve. The illustration is as below:
public void fooConsumer() {
DaggerMyComponent component = DaggerMyComponent.builder.build();
Foo foo = component.foo();
}
Dagger is a way of wiring up graphs of objects and their dependencies. As an alternative to calling constructors directly, you obtain instances by requesting them from Dagger, or by supplying an object that you'd like to have injected with Dagger-created instances.
Let's make a coffee shop, that depends on a Provider<Coffee> and a CashRegister. Assume that you have those wired up within a module (maybe to LightRoastCoffee and DefaultCashRegister implementations).
public class CoffeeShop {
private final Provider<Coffee> coffeeProvider;
private final CashRegister register;
#Inject
public CoffeeShop(Provider<Coffee> coffeeProvider, CashRegister register) {
this.coffeeProvider = coffeeProvider;
this.register = register;
}
public void serve(Person person) {
cashRegister.takeMoneyFrom(person);
person.accept(coffeeProvider.get());
}
}
Now you need to get an instance of that CoffeeShop, but it only has a two-parameter constructor with its dependencies. So how do you do that? Simple: You tell Dagger to make a factory method available on the Component instance it generates.
#Component(modules = {/* ... */})
public interface CoffeeShopComponent {
CoffeeShop getCoffeeShop();
void inject(CoffeeService serviceToInject); // to be discussed below
}
When you call getCoffeeShop, Dagger creates the Provider<Coffee> to supply LightRoastCoffee, creates the DefaultCashRegister, supplies them to the Coffeeshop constructor, and returns you the result. Congratulations, you are the proud owner of a fully-wired-up coffeeshop.
Now, all of this is an alternative to void injection methods, which take an already-created instance and inject into it:
public class CoffeeService extends SomeFrameworkService {
#Inject CoffeeShop coffeeShop;
#Override public void initialize() {
// Before injection, your coffeeShop field is null.
DaggerCoffeeShopComponent.create().inject(this);
// Dagger inspects CoffeeService at compile time, so at runtime it can reach
// in and set the fields.
}
#Override public void alternativeInitialize() {
// The above is equivalent to this, though:
coffeeShop = DaggerCoffeeShopComponent.create().getCoffeeShop();
}
}
So, there you have it: Two different styles, both of which give you access to fully-injected graphs of objects without listing or caring about exactly which dependencies they need. You can prefer one or the other, or prefer factory methods for the top-level and members injection for Android or Service use-cases, or any other sort of mix and match.
(Note: Beyond their use as entry points into your object graph, no-arg getters known as provision methods are also useful for exposing bindings for component dependencies, as David Rawson describes in the other answer.)

castle windsor - batch registration works on some classes only

I am have the following row to batch register implementations:
container.Register(Types.FromAssembly(typeof (BaseBll<>).Assembly)
.BasedOn(typeof (ICrudBll<>)).WithServiceAllInterfaces());
it works on 2 classes out of 4 event though they are exactlly the same.
public interface ICrudBll<T>{} //main interface
public interface IBrandBll : ICrudBll<Brand>{}
public class BrandBll : BaseBll<Brand>, IBrandBll{}// WORKING
public interface IRoleBll : ICrudBll<Role>{}
public class RoleBll : BaseBll<Role>, IRoleBll{}// NOT WORKING
it is suppose to be injected to:
//WORKING
public class BrandController : BaseApiController<Brand>
{
public BrandController(IBrandBll bll) : base(bll)
{
}
}
// NOT WORKING
public class RoleController : BaseApiController<Role>
{
public RoleController(IRoleBll bll)
: base(bll)
{
}
}
I dont see any differences between the classes and the interfaces, but yet some works and some not. (they are all in the same assembly).
This is the ERROR:
Type CrudApp.BusinessLogic.IUserBll is abstract.
As such, it is not possible to instansiate it as implementation of service 'CrudApp.BusinessLogic.IUserBll'. Did you forget to proxy it?
Again, the IBrandBll is working and the IRoleBll not.
I made a test, and injected the failed ones explicitly, and it worked:
container.Register(Component.For<IRoleBll>().ImplementedBy<RoleBll>().LifestyleTransient());
Thanks
Try changing:
container.Register(Types.FromAssembly(typeof (BaseBll<>).Assembly)
.BasedOn(typeof (ICrudBll<>)).WithServiceAllInterfaces());
to
container.Register(Classes.FromAssembly(typeof (BaseBll<>).Assembly)
.BasedOn(typeof (ICrudBll<>)).WithServiceAllInterfaces());
The statements above will also register interfaces, and it seems you only want classes to be registered.
this is actually what worked:
var types = AllTypes
.FromAssembly(typeof (ICrudBll<>).Assembly)
.BasedOn(typeof (ICrudBll<>))
.WithService.FromInterface(typeof (ICrudBll<>));
container.Register(types);
The error clearly states the problem is with IUserBll - not shown in your code snippets.
I bet IUserBll inherits from ICrudBll, which would explain the error - try to narrow down the type selection criteria to classes, excluding the interfaces:
Types.FromAssembly(typeof (BaseBll<>).Assembly)
.BasedOn(typeof (ICrudBll<>))
returns everything, including interfaces. Try something like
Types.FromAssembly(typeof (BaseBll<>).Assembly)
.Where(t => t.IsClass)
.BasedOn(typeof (ICrudBll<>))

Using #Inject with generic type

I've been searching here about it, but haven't found an answer.
In my application, I've an abstract main class for my controllers, with some methods and properties. And I want to inject the DAO automatically.
abstract class AbstractController<E extends AbstractEntity, D extends AbstractDAO<E>> {
#Inject
private D dao;
// getters and setters
}
abstract class AbstractDAO<E extends AbstractEntity> {
#PersistentContext
private EntityManager em;
// finds returns E
}
// implemenation/usage
class CarController extends AbstractController<Car, CarDAO> {
}
Getting the exception:
org.jboss.weld.exceptions.DefinitionException: WELD-001407 Cannot declare an injection point with a type variable: [field] #Inject private AbstractController.dao
Using: Glassfish 3.1 and JSF 2.1.
Is there a workaround or alternative for this?
Thanks.
It's technically very complicated for reflection to detect the proper runtime type by a generic declaration in the source and cast to it. Weld simply don't and won't support it.
Better declare it against AbstractDAO<E>:
private AbstractDAO<E> dao;
You gain nothing with declaring it against D anyway.

How to use a convention for IRepository<T> with StructureMap mapping

Is there a way in StructureMap to do this kind of repetitive mapping with one line or a convention?
For<IRepository<Mailout>>().Use<MailoutRepository>();
For<IRepository<MailServer>>().Use<MailServerRepository>();
For<IRepository<MailoutStatus>>().Use<MailoutStatusRepository>();
For<IRepository<MailoutTemplate>>().Use<MailoutTemplateRepository>();
For<IRepository<Publication>>().Use<PublicationRepository>();
For<IRepository<Recipient>>().Use<RecipientRepository>();
To map IRepository<Mailout> to MailoutRepository, use:
var c = new Container(x =>
{
x.Scan(scan =>
{
// there are other options to expand which assemblies to scan for types
scan.TheCallingAssembly();
scan.ConnectImplementationsToTypesClosing(typeof (IRepository<>));
});
});
To map IRepository<Mailout> to Repository<Mailout>, use:
var c = new Container(x =>
{
x.For(typeof (IRepository<>)).Use(typeof (Repository<>));
});
You could greate something like Repository base :
public class RepositoryBase<T> : IRepository<T> where T : Entity
then have something like this :
public class UserRepository : RepositoryBase<User>, IUserRepository
public class OtherRepository : RepositoryBase<Other>, IOtherRepository
where your repositories interfaces impelement the generic repository interface like that :
public interface IUserRepository : IRepository<User>
public interface IOtherRepository : IRepository<Other>
and then you could register it like that :
For(typeof (IRepository<>)).Use(typeof (RepositoryBase<>));
It works for me.
Here's a workaround, as we couldn't find any shorter way of making that mapping.
First, map to an open generic implementation class, as discussed elsewhere:
For(typeof(IRepository<>)).Use(typeof(ConcreteRepository<>));
Then, for each repository with custom behavior, add extension methods on the appropriate interface. For instance, supposing your MailoutStatusRepository has a method GetStatus(), you might translate that to an extension method on IRepository<MailoutStatusRepository>:
public static Status GetStatus(this IRepository<MailoutStatusRepository> repo,
Mailout mail)
{
return mail.Status; // or whatever
}
Now you have the custom repository behavior without having to worry about casting StructureMap's output to some custom class:
var repo = container.GetInstance<IRepository<MailoutStatusRepository>>();
var status = repo.GetStatus(mailout);
Another benefit of this approach is that your custom repository behavior works regardless of your repository implementation: in tests and in production code. The only downside (I think) is that your repositories are necessarily stateless, but we haven't found this to be a problem at all.
Scan(x =>
{
x.WithDefaultConventions();
x.AssemblyContainingType(typeof(UserRepository));
x.AddAllTypesOf(typeof(Repository<>));
x.ConnectImplementationsToTypesClosing(typeof(IRepository<>));
});
WithDefaultConventions is the important part of the shown code, because with this setting you say StructureMap to use the convention of mappping IUserRepository to UserRepository . So StructureMap proceed from the assumption that the class is named like the name of the interface without the prefix I.

Castle Windsor can't inject an array of interface types

I have a class that takes an array of interfaces in the constructor:
public class Foo<T1, T2> : IFoo<T1, T2>
{
public Foo(IBar[] bars)
{
...
}
}
My container registration looks as follows:
container.Register(AllTypes.Pick().FromAssemblyNamed("...")
.WithService.FirstInterface());
container.AddComponent("foo", typeof(IFoo<,>), typeof(Foo<,>));
I have several implementations of IBar, and the container can definately locate them, as calling ServiceLocator.Current.GetAllInstances<IBar>() works fine.
However, if I try to get an instance of IFoo, it throws an exception saying it couldn't satisfy the deoendency... "which was not registered".
If I change the constructor to take a single instance of IBar it works fine.
Any ideas?
Add the ArrayResolver:
container.Kernel.Resolver.AddSubResolver(new ArrayResolver(container.Kernel));

Resources