IOC using AutoFac for internal class - class

I have an internal class which is internal visible to a service Factory. It is also inheriting an public interface.
When I want to use its functionality in my application, I am declaring object for the interface and getting it instantiated for the particular class through service factory.
Now we are using MVC and I want to create IOC for this class in my one of the controller.
This class being internal, I can not register this in global.ascx
For example when I am writing
builder.RegisterType().As().InstancePerHttpRequest() ;
The CommonSvc being internal, it is throwing compile time error as Services.CommonSvc' is inaccessible due to its protection level
Please advise

Your options:
Make CommonSvc public
Annotate your assembly with an InternalsVisibleToAttribute to make internal types visible to the calling assembly.
Instead of registering CommonSvc directly, use RegisterAssemblyTypes() to register it by convention. For example:
builder.RegisterAssemblyTypes(typeof(SomeOtherTypeInTheSameAssembly).Assembly)
.Where(t => typeof(SomeInterface).IsAssignableFrom(t))
.AsImplementedInterfaces();

Related

In Dagger, does an Inject annotated class also act as a Provider?

I am new to Dagger (version 2.16 on Android) and based on my reading so far, I understand that for a component, there should be a provider (#Provides or #Binds) encapsulated in a module (#Module). Going through a lot of samples, I see code which has some objects which are not offered in any Module, nor are they being instantiated using new.
It is also my understanding that in order to access the dependencies in a module, a consumer class needs to inject itself in the component graph (components usually offer a method to inject classes). The code examples are not doing this either.
Here's some code demonstrating both my concerns. RecipePresenter is not being provided in any module, but still RecipeActivity is using it.
A possible explanation I could think of is that #Inject, in addition to requesting the dependency also adds/injects the requesting class (RecipePresenter in the linked code) into the component graph. But assuming there are multiple components/subcomponents, which component does the class using #Inject constructor gets attached to? If my understanding is correct, why do activities and fragments have to inject themselves manually in the component - shouldn't they be auto-injected if they declare a variable annotated with #Inject?
RecipePresenter has an #Inject-annotated constructor, which allows it to be provided. The #Inject annotation on the recipePresenter field within RecipeActivity does not help, just the #Inject-annotated constructor.
class RecipePresenter #Inject constructor(
private val useCase: RecipeUseCase,
private val res: StringRetriever) :
RecipeUseCase.Callback {
From the Dagger User's Guide:
Use #Inject to annotate the constructor that Dagger should use to create instances of a class. When a new instance is requested, Dagger will obtain the required parameters values and invoke this constructor.
If the class with the #Inject-annotated constructor also has a defined scope, then the binding will only affect components with the same scope annotation: An #ActivityScope class wouldn't be accessible from a #Singleton component, for instance. If the class has no scope defined, then the binding could appear on any and all components where it is needed, which is fine: The implementation is always the same, defined by the constructor itself.
#Inject has different meanings based on what it's annotating:
When you annotate a field with #Inject, it indicates that the DI system should set that field based on values from the DI system when it injects that object.
When you annotate a method with #Inject, it indicates that the DI system should call that method with parameters based on values from the DI system when it injects that object.
When you annotate a constructor with #Inject, it indicates that the DI system is allowed to call that constructor in order to create that object (which triggers the field and method injection above). In that sense it does act like a built-in Provider.
In Dagger specifically, #Provides methods take precedence over #Inject constructors (if they both exist for the same class), and unlike in the JSR-330 spec Dagger requires an #Inject-annotated constructor even when no other constructors are present. From the Dagger User's Guide:
If your class has #Inject-annotated fields but no #Inject-annotated constructor, Dagger will inject those fields if requested, but will not create new instances. Add a no-argument constructor with the #Inject annotation to indicate that Dagger may create instances as well.
Classes that lack #Inject annotations cannot be constructed by Dagger.
Finally, to answer your question about why activities and fragments need to inject themselves: Android is allowed to reflectively create Activity/Fragment/View objects without Dagger's help or participation. This means that nothing triggers the field and method injection described above, until you call a members-injection method on the component that instructs Dagger to populate those fields and call those methods. Consequently, you should never see an #Inject-annotated constructor on Application, Activity, Service, Fragment, View, ContentProvider, and BroadcastReceiver subclasses in Android: Android will ignore the #Inject annotation, so you might as well take control over injection yourself, manually or through dagger.android.

What does kernel.Bind<SomeType>().ToSelf() do?

I understand the following Ninject registration:
kernel.Bind<ISomeType>().To<SomeTypeImplementation>();
which tells Ninect to fulfill requests for ISomeType by using SomeTypeImplementation.
However I'm not sure what the following is good for.
kernel.Bind<ApplicationDbContext>().ToSelf();
Which was suggested that I use from this question:
What ninject binding should I use?
It makes ApplicationDbContext "self-bindable". If you don't have an interface to bind to, you can bind to the class itself. It's more useful if you add a scope to the call such as:
kernel.Bind<ApplicationDbContext>().ToSelf().InRequestScope();
Any time it sees the ApplicationDbContext that needs to be injected, it will reuse the same object as long as it is in the same HTTP request.
The default scope is transient, which means that any time a class requests ApplicationDbContext it will create a new instance of it. This can be problematic if you have two classes that both need to use the context in the same transaction. That is why you will often see it done with InRequestScope().
By self-binding a type, you enable that type for the following:
Lifecycle Management by the container.
Enable the container to inject dependencies into other types that depend on the self-bound type, and inject dependencies of this type into its instances likewise.
Very useful if you just have one single implementation or you don't need to use abstractions for some reason.

JAXRS tries to call Interface instead of Implementation

I got a JAXRS application. I have an Interface class (SomeResource) (where i put most of my annotations) and an implementation of this interface (SomeService).
I have registered the SomeService.class in the overriden JaxRSApplication method .getClasses();
All my other services/resources are implemented in the same way, but whenever i try to call this one service (SomeService), i get the following exception:
"Error 500: javax.servlet.ServletException: java.lang.IllegalAccessException: Class org.apache.wink.server.internal.handlers.InvokeMethodHandler can not access a member of class package.api.SomeResource with modifiers "public abstract""
As you can see, for some reason, this one Service tries to call the Resource(Interface) instead of the the Service class with the actual implementation.
Anyone got an idea how to resolve this? (Real classnames hidden because of security).
Be sure to declare the implementation class of the service (SomeService.class) with its full qualified classname and not the interface within your rest service configurationen of your application.
The way you have to do that depends on the implementing framework.
Have a look here:
http://cxf.apache.org/docs/jaxrs-services-configuration.html

how can I use an interface entity in RequestFactory's client-side?

I have some service methods which return entities that are not implemented yet.
For example, I have an interface called IUser and some classes that implemented this interface such as GuestUser and AdminUser.
All entity classes are well-defined already and I want to use their jar files without manipulating them.
My problem is when I wanted to define ProxyFor IUser.class in client-side entity and to call service methods that their return type are IUser. While calling these methods I get the following error: The domain type com.bis.entity.security.GuestUser cannot be sent to the client.
Is there any way to call methods that deal with interfaces in RequestFactory or do I have to change all the service methods to utilize class entitis?
You have to use classes for now. See http://code.google.com/p/google-web-toolkit/issues/detail?id=5762

RIAServices unsupported types on hand-built DomainService

My EF model was generated from my SQL Server database. I then generated a DomainService for RIAServices against the EF model. One of the entities is called "EntryCategories". The DomainService created this method:
public IQueryable<EntryCategories> GetEntryCategoriesSet()
{
return this.Context.EntryCategoriesSet;
}
Since my user interface display model looks quite different from the physical model, I decided to write my own DomainService for that and related entities. Yes, I know we are meant to modify the generated one but it has so much stuff in there and I wanted to focus on a small thing.
I removed the EnableClientAccess attribute from the generated DomainService and added a new class called ClientDomainService, and encapsulated in it the generated DomainService:
[EnableClientAccess()]
public class ClientDomainService : DomainService
{
// the generated domain service encapsulated in my new one.
private DataDomainService _dcds = new DataDomainService();
// reimplement one of the DataDomainService methods
public IQueryable<EntryCategories> GetEntryCategories()
{
return (from t in _dcds.GetEntryCategoriesSet() where t.EntryCategoriesVersions.EntryCategoriesVersionId == datahead.EntryCategoriesVersions.EntryCategoriesVersionId orderby t.DisplayOrder select t);
}
}
The very fist thing I tried is to reimplement the GetCateogoriesSet method but with the underlying data filtered based on another entity in my class (not shown). But when I build this, an error shows up:
Entity 'DataProject.Web.EntryCategories' has a property 'EntryCategoriesVersionsReference' with an unsupported type
If I comment out my CientDomainService, replace the EnableClientAccess attribute on the generated DomainService, and place the analagous linq filtering in the original GetEntryCategoriesSet method, the project compiles with no errors.
What is so special about the generated DomainService that my new one doesn't have? Is it that metadata.cs file?
What's special about the generated domain service is not the .metadata.cs file (you can keep it, and use it, but it doesn't solve your problem).
The problem appears somehow because RIA services (?) needs a 'domain service description provider' for the exposed Linq to EF entities. The LinqToEntitiesDomainService class has the LinqToEntitiesDomainServiceDescriptionProviderAttribute, already applied, so the generated domain services which inherit from it also inherit the provider.
When you build your own custom domain service, derived from DomainService, and expose entities through it, you need to apply this attribute yourself. Furthermore, since the provider cannot infer the object context type from the domain service base class (which it can and does if the base class is LinqToEntitiesDomainService), you need to specify the object context type in the attribute constructor, like this:
[EnableClientAccess()]
[LinqToEntitiesDomainServiceDescriptionProvider(
typeof(YourObjectContextType))]
public class ClientDomainService : DomainService
{
...
}
That should fix it.
Note that this means if you had hoped to abstract your object context away from your domain service, you'll be disappointed. I had opted for the seemingly popular repository model where all code that operates on the object context goes into a provider used by the domain service. This facilitates unit testing, but evidently doesn't remove the domain service's dependency on the object context. The context is required for RIA Services to make sense of your entites, or at least those referenced by the domain entity (such as EntryCategoriesVersions in your case).
If you want to expose a specific entity on a domain service you will have to provde at least one query method for it. This is also required when the entity is only accessed as a child of another entity.
In this case you need to add the EntryCategoriesVersions entityset to the domain service, to get the scenario working correctly.
What type is EntryCategoriesVersionsReference ? Try adding a [DataContract] annotation against the type, and appropriate [Key] and [DataMember]. It should help with marshalling.
For me, the fix for this error was to add a default constructor to the return type.
In OP's example, the property 'EntryCategories.EntryCategoriesVersionsReference' needs to be of a type with a default constructor.