I'm trying to configure IoC (concept I'm not very familiar with yet) in my SF in a stateful service as explained here : https://www.codeproject.com/Articles/1217885/Azure-Service-Fabric-demo and here : https://alexmg.com/posts/introducing-the-autofac-integration-for-service-fabric.
in program.cs - main:
var builder = new ContainerBuilder();
builder.RegisterModule(new GlobalAutofacModule());
builder.RegisterServiceFabricSupport();
builder.RegisterStatefulService<Payment>("PaymentType");
using (builder.Build())
{
ServiceEventSource.Current.ServiceTypeRegistered(Process.GetCurrentProcess().Id, typeof(Payment).Name);
Thread.Sleep(Timeout.Infinite);
}
GlobalAutofacModule :
public class GlobalAutofacModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<ChargeRepository>().As<IChargeRepository>().SingleInstance();
builder.RegisterType<CustomerRepository>().As<ICustomerRepository>().SingleInstance();
builder.RegisterType<InvoiceItemRepository>().As<IInvoiceItemRepository>().SingleInstance();
builder.RegisterType<PlanRepository>().As<IPlanRepository>().SingleInstance();
builder.RegisterType<ProductRepository>().As<IProductRepository>().SingleInstance();
builder.RegisterType<SourceRepository>().As<ISourceRepository>().SingleInstance();
builder.RegisterType<SubscriptionRepository>().As<ISubscriptionRepository>().SingleInstance();
builder.RegisterType<TokenRepository>().As<ITokenRepository>().SingleInstance();
}
}
the service is called without problems
public Payment(StatefulServiceContext context,
IChargeRepository chargeRepo,
ICustomerRepository customerRepo,
IInvoiceItemRepository invoiceItemRepo,
IPlanRepository planRepository,
IProductRepository productRepo,
ISourceRepository sourceRepo,
ISubscriptionRepository subscriptionRepo,
ITokenRepository tokenRepo)
: base(context)
{ ... }
in one of it's methodes it needs to call a custom mapper (error on missing params)
var test = new Mapper().GetProductsDto(false, false);
the class is defined like this :
private readonly IChargeRepository _chargeRepo;
private readonly ICustomerRepository _customerRepo;
private readonly IInvoiceItemRepository _invoiceItemRepo;
private readonly IPlanRepository _planRepo;
private readonly IProductRepository _productRepo;
private readonly ISourceRepository _sourceRepo;
private readonly ISubscriptionRepository _subscriptionRepo;
private readonly ITokenRepository _tokenRepo;
public Mapper(IChargeRepository chargeRepo,
ICustomerRepository customerRepo,
IInvoiceItemRepository invoiceItemRepo,
IPlanRepository planRepository,
IProductRepository productRepo,
ISourceRepository sourceRepo,
ISubscriptionRepository subscriptionRepo,
ITokenRepository tokenRepo)
{
_chargeRepo = chargeRepo;
_customerRepo = customerRepo;
_invoiceItemRepo = invoiceItemRepo;
_planRepo = planRepository;
_productRepo = productRepo;
_sourceRepo = sourceRepo;
_subscriptionRepo = subscriptionRepo;
_tokenRepo = tokenRepo;
}
public IEnumerable<ProductListDto> GetStripeProductsDto(bool isLogged, bool isSubscriber) {...}
So how do I instantiate the mapper and call the method without passing every repo as params ?
EDIT: tmp solution until approuved/disapprouved
private static void Main()
{
try
{
using (ContainerOperations.Container)
{
ServiceEventSource.Current.ServiceTypeRegistered(Process.GetCurrentProcess().Id, typeof(Payment).Name);
Thread.Sleep(Timeout.Infinite);
}
}
catch (Exception e)
{
ServiceEventSource.Current.ServiceHostInitializationFailed(e.ToString());
throw;
}
}
}
public class ContainerOperations
{
private static readonly Lazy<IContainer> _containerSingleton =
new Lazy<IContainer>(CreateContainer);
public static IContainer Container => _containerSingleton.Value;
private static IContainer CreateContainer()
{
var builder = new ContainerBuilder();
builder.RegisterModule(new GlobalAutofacModule());
builder.RegisterServiceFabricSupport();
builder.RegisterStatefulService<Payment>("Inovatic.SF.Windows.PaymentType");
return builder.Build();
}
}
public class GlobalAutofacModule : Module
{
protected override void Load(ContainerBuilder builder)
{
//builder.RegisterType<Mapper>();
builder.RegisterType<ChargeRepository>().As<IChargeRepository>().SingleInstance();
builder.RegisterType<CustomerRepository>().As<ICustomerRepository>().SingleInstance();
builder.RegisterType<InvoiceItemRepository>().As<IInvoiceItemRepository>().SingleInstance();
builder.RegisterType<PlanRepository>().As<IPlanRepository>().SingleInstance();
builder.RegisterType<ProductRepository>().As<IProductRepository>().SingleInstance();
builder.RegisterType<SourceRepository>().As<ISourceRepository>().SingleInstance();
builder.RegisterType<SubscriptionRepository>().As<ISubscriptionRepository>().SingleInstance();
builder.RegisterType<TokenRepository>().As<ITokenRepository>().SingleInstance();
}
}
call is now like this : var productListDto = Mapper.GetStripeProductsDto(isLogged, false);
mapper:
private static IProductRepository _productRepo => ContainerOperations.Container.Resolve<IProductRepository>();
public static IEnumerable<ProductListDto> GetStripeProductsDto(bool isLogged, bool isSubscriber)
{
var productList = _productRepo.GetAllStripeProducts().ToList();
I think you should also register Mapper class in IoC container and add it to Payment's constructor, then container will create Mapper with all required params for you. You can do it calling something like
builder.RegisterType<Mapper>().SingleInstance();
Related
I am using aspnetboilerplate template
i have a student service class. i am getting a student profile List from stored procedure. how can i call a stored procedure in aspnetboilerplate template
public class StudentRepository : TabonoRepositoryBase<User, long>
{
private readonly IActiveTransactionProvider _transactionProvider;
public StudentRepository(IDbContextProvider<TabonoDbContext> dbContextProvider, IActiveTransactionProvider transactionProvider)
: base(dbContextProvider)
{
_transactionProvider = transactionProvider;
}
//TODO: Make async!
public async Task<int> GetProfileCompletePercentage(int studentid)
{
EnsureConnectionOpen();
using (var command = CreateCommand("Sp_GetStudentprofilepercentage", CommandType.StoredProcedure, new SqlParameter("StudentId", studentid)))
{
using (var dataReader = await command.ExecuteReaderAsync())
{
while (dataReader.Read())
{
return Convert.ToInt16(dataReader["TotalPer"].ToString());
}
return 0;
}
}
}
private DbCommand CreateCommand(string commandText, CommandType commandType, params SqlParameter[] parameters)
{
var command = Context.Database.GetDbConnection().CreateCommand();
command.CommandText = commandText;
command.CommandType = commandType;
command.Transaction = GetActiveTransaction();
foreach (var parameter in parameters)
{
command.Parameters.Add(parameter);
}
return command;
}
private void EnsureConnectionOpen()
{
var connection = Context.Database.GetDbConnection();
if (connection.State != ConnectionState.Open)
{
connection.Open();
}
}
private DbTransaction GetActiveTransaction()
{
return (DbTransaction)_transactionProvider.GetActiveTransaction(new ActiveTransactionProviderArgs
{
{"ContextType", typeof(TabonoDbContext) },
{"MultiTenancySide", MultiTenancySide }
});
}
}
And this is the service class
public class StudentService : AsyncCrudAppService<StudentCore, StudentDto, int, PagedResultRequestDto, StudentCreateDto, StudentUpdateDto>, IStudentService
{
public readonly IRepository<StudentCore> _studentRepository;
private readonly UserManager _userManager;
private readonly IStudentService _studentservice;
public StudentService(IRepository<StudentCore> repository, UserManager um, IStudentService studentservice) : base(repository)
{
_studentRepository = repository;
_userManager = um;
_studentservice = studentservice;
}
public Task GetProfileCompletePercentage(int studentid)
{
return _studentservice.GetProfileCompletePercentage(studentid);
}
}
Create an interface:
public interface IStudentRepository : IRepository<StudentCore>
{
Task<int> GetProfileCompletePercentage(int studentid);
}
Implement the interface:
public class StudentRepository : TabonoRepositoryBase<StudentCore>, IStudentRepository
{
// ...
}
Inject the interface and call the method:
public class StudentService : ...
{
private readonly IStudentRepository _studentRepository;
public StudentService(IStudentRepository repository) : base(repository)
{
_studentRepository = repository;
}
public Task GetProfileCompletePercentage(int studentid)
{
return _studentRepository.GetProfileCompletePercentage(studentid);
}
}
Note: StudentService must not inject IStudentService in constructor → infinite recursion!
For reference: https://www.codeproject.com/Articles/1199648/Using-Stored-Procedure-User-Defined-Function-and-V
I've been at it for days, but I can't get Unity to inject anything with RegisterType<> into my Controller. I'm using Web Api 2, in Visual Studio 2015, with Unity 4. Whenever I try to inject IUnitOfWork or IRFContext, I get "message": "An error occurred when trying to create a controller of type 'ClPlayersController'. Make sure that the controller has a parameterless public constructor.".
I'm using the Unity.AspNet.WebApi to bootstrapp into WebApi. Below is my UnityWebApiActivator
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(mycompany.project.api.UnityWebApiActivator), "Start")]
[assembly: WebActivatorEx.ApplicationShutdownMethod(typeof(mycompany.project.api.UnityWebApiActivator), "Shutdown")]
namespace mycompany.project.api
{
public static class UnityWebApiActivator
{
public static void Start()
{
var resolver = new UnityDependencyResolver(UnityConfig.GetConfiguredContainer());
GlobalConfiguration.Configuration.DependencyResolver = resolver;
}
public static void Shutdown()
{
var container = UnityConfig.GetConfiguredContainer();
container.Dispose();
}
}
}
I'm using a Start.cs due to Owin.
[assembly: OwinStartup(typeof(mycompany.project.api.Startup))]
namespace mycompany.project.api
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
HttpConfiguration config = new HttpConfiguration();
ConfigureOAuth(app);
config.DependencyResolver = new UnityDependencyResolver(UnityConfig.GetConfiguredContainer());
WebApiConfig.Register(config);
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.UseWebApi(config);
}
public void ConfigureOAuth(IAppBuilder app)
{
OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
Provider = new SimpleAuthorizationServerProvider(),
RefreshTokenProvider = new SimpleRefreshTokenProvider()
};
// Token Generation
app.UseOAuthAuthorizationServer(OAuthServerOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
}
}
}
My WebApiConfig.cs is below:
namespace mycompany.project.api
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
log4net.Config.XmlConfigurator.Configure();
config.MapHttpAttributeRoutes();
config.EnableSystemDiagnosticsTracing();
config.Services.Add(typeof(IExceptionLogger),
new SimpleExceptionLogger(new LogManagerAdapter()));
config.Services.Replace(typeof(IExceptionHandler), new GlobalExceptionHandler());
}
}
}
My UnityConfig.cs is below
namespace mycompany.project.api
{
public class UnityConfig
{
#region Unity Container
private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
{
var container = new UnityContainer();
RegisterTypes(container);
return container;
});
public static IUnityContainer GetConfiguredContainer()
{
return container.Value;
}
#endregion
public static void RegisterTypes(IUnityContainer container)
{
var config = new MapperConfiguration(cfg =>
{
//AutoMapper bindings
});
container.RegisterInstance<IMapper>(config.CreateMapper());
container.RegisterType<IRFContext, RFContext>(new PerThreadLifetimeManager());
container.RegisterType<IUnitOfWork, UnitOfWork>();
XmlConfigurator.Configure();
var logManager = new LogManagerAdapter();
container.RegisterInstance<ILogManager>(logManager);
}
}
}
All that I have in my Global.asax is below:
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Error()
{
var exception = Server.GetLastError();
if (exception != null)
{
var log = new LogManagerAdapter().GetLog(typeof(WebApiApplication));
log.Error("Unhandled exception.", exception);
}
}
}
If my Controller is like this, it works fine:
public class ClPlayersController : ApiController
{
private readonly IMapper mapper;
public ClPlayersController(IMapper _mapper, IUnityContainer container)
{
mapper = _mapper;
}
But placing IUnitOfWork, like below, or the IRFContext, I get the error:
private readonly IMapper mapper;
private readonly IUnitOfWork unitOfWork;
public ClPlayersController(IMapper _mapper, IUnityContainer container, IUnitOfWork _unitOfWork)
{
mapper = _mapper;
unitOfWork = _unitOfWork;
}
I can't find, for the life of me, what I'm doing wrong. If I loop through the container.Registrations on the constructor, I find the mappings, but they refuse to get injected. Any hints?
EDIT
Below is the code for UnitOfWork and RFContext
namespace mycompany.project.data.configuracao
{
public class UnitOfWork : IUnitOfWork
{
private readonly IRFContext _rfContext;
private bool _disposed = false;
public UnitOfWork(IRFContext rfContext)
{
_rfContext = rfContext;
}
public void Commit()
{
if (_disposed)
{
throw new ObjectDisposedException(this.GetType().FullName);
}
_rfContext.SaveChanges();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (_disposed) return;
if (disposing && _rfContext != null)
{
_rfContext.Dispose();
}
_disposed = true;
}
}
}
and
namespace mycompany.project.data.configuracao
{
public interface IUnitOfWork : IDisposable
{
void Commit();
}
}
and RFContext is a basic POCO generated DBContext
namespace mycompany.project.data.configuracao
{
using System.Linq;
public class RFContext : System.Data.Entity.DbContext, IRFContext
{
public System.Data.Entity.DbSet<ClGrupoEconomico> ClGrupoEconomicoes { get; set; }
//all my DbSets
public System.Data.Entity.DbSet<SpTipoLog> SpTipoLogs { get; set; }
static RFContext()
{
System.Data.Entity.Database.SetInitializer<RFContext>(null);
}
public RFContext()
: base("Name=RFContext")
{
}
public RFContext(string connectionString)
: base(connectionString)
{
}
public RFContext(string connectionString, System.Data.Entity.Infrastructure.DbCompiledModel model)
: base(connectionString, model)
{
}
public RFContext(System.Data.Common.DbConnection existingConnection, bool contextOwnsConnection)
: base(existingConnection, contextOwnsConnection)
{
}
public RFContext(System.Data.Common.DbConnection existingConnection, System.Data.Entity.Infrastructure.DbCompiledModel model, bool contextOwnsConnection)
: base(existingConnection, model, contextOwnsConnection)
{
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
}
protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Configurations.Add(new ClGrupoEconomicoConfiguration());
//all my Configuration classes
modelBuilder.Configurations.Add(new SpTipoLogConfiguration());
}
public static System.Data.Entity.DbModelBuilder CreateModel(System.Data.Entity.DbModelBuilder modelBuilder, string schema)
{
modelBuilder.Configurations.Add(new ClGrupoEconomicoConfiguration(schema));
//all my configuration classes
modelBuilder.Configurations.Add(new SpTipoLogConfiguration(schema));
return modelBuilder;
}
}
}
Unfortunately the exception you are seeing can occur for several reasons. One of them is when Unity cannot resolve one or more of your injections.
An error occurred when trying to create a controller of type
'FooController'. Make sure that the controller has a parameterless
public constructor.
So, based on the information in your question your setup is apparently correct, since IMapper can be injected. Therefore I guess that UnitOfWork and RFContext have dependencies that Unity cannot resolve. Maybe a repository?
UPDATE:
The problem here is that your RFContext has several constructors.
https://msdn.microsoft.com/en-us/library/cc440940.aspx#cnstrctinj_multiple
When a target class contains more than one constructor with the same
number of parameters, you must apply the InjectionConstructor
attribute to the constructor that the Unity container will use to
indicate which constructor the container should use. As with automatic
constructor injection, you can specify the constructor parameters as a
concrete type, or you can specify an interface or base class for which
the Unity container contains a registered mapping.
In this case Unity doesn't know how to resolve your RFContext, and will try to use the constructor with the most parameters. You can solve it by using
container.RegisterType<IRFContext, RFContext>(new InjectionConstructor());
I am working on an ASP.NET WebAPI using OWIN. To manage the instances of DBContext (Entity Framework), I try to use Ninject. However, when I call a controller, the programm returns an error:
The controller cannot be created, missing constructor.
Could you tell me what is going wrong here?
My Controller Class:
public class Testcontroller
{
private IApplicationDbContext _context;
public Testcontroller(IApplicationDbContext context)
{
_context = context;
}
}
This is the Ninject-File:
public static class NinjectWebCommon
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}
public static void Stop()
{
bootstrapper.ShutDown();
}
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
try
{
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
kernel.Bind<IApplicationDbContext>().To<ApplicationDbContext>();
GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
RegisterServices(kernel);
return kernel;
}
catch
{
kernel.Dispose();
throw;
}
}
private static void RegisterServices(IKernel kernel)
{
}
}
Ninject Dependency Scope:
public class NinjectDependencyScope : IDependencyScope
{
IResolutionRoot resolver;
public NinjectDependencyScope(IResolutionRoot resolver)
{
this.resolver = resolver;
}
public object GetService(Type serviceType)
{
if (resolver == null)
throw new ObjectDisposedException("this", "This scope has been disposed");
return resolver.TryGet(serviceType);
}
public System.Collections.Generic.IEnumerable<object> GetServices(Type serviceType)
{
if (resolver == null)
throw new ObjectDisposedException("this", "This scope has been disposed");
return resolver.GetAll(serviceType);
}
public void Dispose()
{
IDisposable disposable = resolver as IDisposable;
if (disposable != null)
disposable.Dispose();
resolver = null;
}
}
// This class is the resolver, but it is also the global scope
// so we derive from NinjectScope.
public class NinjectDependencyResolver : NinjectDependencyScope, IDependencyResolver
{
IKernel kernel;
public NinjectDependencyResolver(IKernel kernel) : base(kernel)
{
this.kernel = kernel;
}
public IDependencyScope BeginScope()
{
return new NinjectDependencyScope(kernel.BeginBlock());
}
}
The Entity Framework DbContext-Class:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>, IApplicationDbContext
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
Configuration.ProxyCreationEnabled = false;
Configuration.LazyLoadingEnabled = false;
}
public virtual DbSet<Models.Team> Teams { get; set; }
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
public interface IApplicationDbContext
{
DbSet<Models.Team> Teams { get; set; }
int SaveChanges();
Task<int> SaveChangesAsync(CancellationToken cancellationToken);
}
I tried to follow this tutorial: http://www.peterprovost.org/blog/2012/06/19/adding-ninject-to-web-api
What have I done wrong here?
Thanks in advance!
Unless there was a serious omission in you controller code, your controller is not inheriting from ApiController, as is expected with Web Api
public class TestController : ApiController {
private IApplicationDbContext _context;
public Testcontroller(IApplicationDbContext context) {
_context = context;
}
}
UPDATE
I tried to set up everything from scratch using this: http://www.alexzaitzev.pro/2014/11/webapi2-owin-and-ninject.html
For some reason, it now works out perfectly fine.
Thank you for your support!
I want to use IOC with my service and I want to instead inject a class not an interface in the constructor as below in the services layer but I do not want to create a new object from the calling layer like var service = new InvoiceService(new ChangeInvoiceDueDateCommand()) instead I want to create something like this from my controller in MVC where the IInvoiceService is injected into the controller constructor but the problem I see is that
public InvoiceController(IInvoiceService invoiceService, IMapper mapper)
{
_invoiceService = invoiceService;
_mapper = mapper;
}
and then called like this
public ActionResult ChangeInvoiceDueDate(InvoiceChangeDueDateViewModel invoiceChangeDueDateViewModel )
{
var request = _mapper.Map<InvoiceChangeDueDateViewModel, ChangeInvoiceDuedateRequest>(invoiceChangeDueDateViewModel);
InvoiceChangeDueDateResponse response = _invoiceService.ChangeDueDate(request);
return View();
}
Service Layer
public class InvoiceService : IInvoiceService
{
private readonly ChangeInvoiceDueDateCommand _changeInvoiceDueDateCommand;
public InvoiceService(ChangeInvoiceDueDateCommand changeInvoiceDueDateCommand)
{
_changeInvoiceDueDateCommand = changeInvoiceDueDateCommand;
}
public InvoiceChangeDueDateResponse ChangeDueDate(ChangeInvoiceDuedateRequest invoiceChangeDueDateRequest)
{
_changeInvoiceDueDateCommand.Execute(invoiceChangeDueDateRequest);
return new InvoiceChangeDueDateResponse {Status = new Status()};
}
}
Command
public class ChangeInvoiceDueDateCommand : ICommand<ChangeInvoiceDuedateRequest>
{
private readonly IRepository<Invoice> _invoiceRepository;
readonly InvoiceDueDateChangeValidator _validator;
public ChangeInvoiceDueDateCommand(IRepository<Invoice> invoiceRepository)
{
_invoiceRepository = invoiceRepository;
_validator = new InvoiceDueDateChangeValidator();
}
public void Execute(ChangeInvoiceDuedateRequest request)
{
if (_validator.IsDuedateValid(request.NewDuedate))
{
Invoice invoice = _invoiceRepository.GetById(request.Id);
invoice.ChangedDueDate(request.NewDuedate);
_invoiceRepository.SaveOrUpdate(invoice);
}
else
{
throw new InvalidDueDateException();
}
}
}
ICommand
public interface ICommand<T> where T : IRequest
{
void Execute(T request);
}
IRequest
public interface IRequest
{
int Id { get; set; }
}
I worked it out. It was just a Windsor syntax issue. It ended up being as simple as registering the Command using the container.Register(Component.For<ChangeInvoiceDueDateCommand>());
I am having a hard time figuring out how to inject CachedRithms into my RithmioManager and CachedKamms into my KamilManager?
I have the following files:
AppScopeModule:
#Module
(
library = true,
complete = false,
injects = {
KamilApplication.class,
KamilManager.class
}
)
public class AppScopeModule {
/* package */ static Context sApplicationContext = null;
private final Context mApplicationContext;
AppScopeModule(Context applicationContext) {
KamilManager.initInstance(applicationContext);
mApplicationContext = applicationContext;
}
#Provides
#Singleton
KamilManager provideKamilManager() {
return KamilManager.getInstance();
}
}
KamilApplication:
public class KamilApplication extends Application implements Injector {
private ObjectGraph mObjectGraph;
#Inject
KamilManager KamilManager;
#Override
public void onCreate() {
super.onCreate();
AppScopeModule sharedAppModule = new AppScopeModule(this);
// bootstrap. So that it allows no-arg constructor in AppScopeModule
sharedAppModule.sApplicationContext = this.getApplicationContext();
List<Object> modules = new ArrayList<Object>();
modules.add(sharedAppModule);
modules.add(new AuthModule());
modules.addAll(getAppModules());
mObjectGraph = ObjectGraph.create(modules.toArray());
mObjectGraph.inject(this);
}
}
KamilManager
public class KamilManager {
#Inject
CachedKamms mCachedKamms;
private static KamilManager instance;
private boolean mWearIsConnectedToMobile;
private KamilManager() {
Log.d(TAG, "KamilManager private constructor");
}
public static void initInstance(Context appContext) {
if (instance == null) {
instance = new KamilManager();
.....doing more things here...
}
}
public static KamilManager getInstance() {
return instance;
}
}
But mCAchedKamms is always blank when I initialize the app. Any idea what I'm doing wrong?
You need to call ObjectGraph.inject(this) somewhere in KamilManager.
I suggest you to add this code to your KamilApplication class:
public ObjectGraph getObjectGraph() {
return mObjectGraph;
}
After that you need to somehow get instance of KamilApplication(pass it via constructor maybe?) in KamilManager and call:
kamilApplication.getObjectGraph.inject(this);
after this call every field in class KamilManager annotated with #Inject should be injected.
OR
Just annotate constructor of CachedKamms with #Inject
Extra:
Avoid of using library = true and complete = false unless you know what are you doing. With this settings you disable some validations at compile time.