How can I use jackson mix-in with firebase Java lib? I would to add #JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY) to a third party lib with mix in.
Update
I create a mix in and a module:
public interface CustomTabMixIn {
#JsonIgnore boolean isCustomObject();
}
public class SFMetadataModule extends SimpleModule
{
public SFMetadataModule() {
super("SF-Metadata", new Version(0,0,1,null));
}
#Override
public void setupModule(SetupContext context)
{
context.setMixInAnnotations(com.sforce.soap.metadata.CustomTab.class, CustomTabMixIn.class);
}
}
How can I register my module with firebase?
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new SFMetadataModule());
Related
I'm trying to configure an API which a controller use depency injection to inject an object to this controller
public class BaseAPIController
{
private readonly Repository _repository;
public BaseAPIController(Repository repository)
{
_repository = repository;
}
// some common functions and properties are declared here
}
public class AccountController : BaseAPIController
{
public AccountController(Repository repository) : base(repository)
{ }
}
but it throws an exception that tells "Some services are not able to be constructed..."
I tried a solution that use ILogger<Repository> instead of using Repository instance then this runs properly
public class AccountController : BaseAPIController
{
public AccountController(ILogger<Repository> repository) : base(repository)
{ }
}
the registion service in startup.cs code
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddScoped<IRepository, Repository>();
services.AddSingleton<WeatherForecastController, WeatherForecastController>();
}
and the declaration of Repository class
public interface IRepository
{
void DoSomething1();
void DoSomething2();
void DoSomething3();
}
public class Repository : IRepository
{
public readonly string _connectionString;
public Repository(string connectionString)
{
_connectionString = connectionString;
}
public void DoSomething1() {}
public void DoSomething2() {}
public void DoSomething3() {}
}
How can I archive the configuration above without using ILogger instance
Thanks
This is the registration you made:
services.AddScoped<IRepository, Repository>();
But this is AccountController's constructor:
AccountController(Repository repository)
Notice how AccountController is depending on the concrete type Repository; not on the IRepository interface. Because of this registration, Repository can only be resolved through its IRepository interface, but not directly (that's by MS.DI's design).
The solution, therefore, is to change AccountController's constructor to the following:
AccountController(IRepository repository)
The issue is that DI cannot create an instance of Repository because there is no parameterless constructor. Take a look at the docs for injecting settings rather than requiring a string in the constructor. Add your connection string to your appsettings.json file:
{
"AppSettings": {
"ConnectionString": "<connection_string>"
}
}
In ConfigureServices register your settings class:
public class AppSettings
{
public string ConnectionString;
}
public void ConfigureServices(IServiceCollection services)
{
services.Configure<AppSettings>(Configuration.GetSection(AppSettings));
...
}
Then your Repository class constructor would look like this:
public Repository(IOptions<PositionOptions> options)
{
_connectionString = options.Value.ConnectionString;
}
You also need to inject the interface IRepository, not the concrete class into your controller.
public class BaseAPIController
{
private readonly IRepository _repository;
public BaseAPIController(IRepository repository)
{
_repository = repository;
}
// some common functions and properties are declared here
}
I am trying to implement MEF framework in my .Net core and .Net framework application. Here is my sample.
Project One class library:
[Export(typeof(IProductRepository))]
public class ProductRepository : IProductRepository
{
public ProductRepository(ApplicationDBContext context)
{
this.context = context;
}
}
Project Two class library:
[Export(typeof(IProductService))]
public class ProductService : IProductService
{
public ProductService(IProductRepository _ProductRepository)
{
}
}
So here both project depends on interface injection on constructor, and in another class library i am implementing the MEF like
[System.Composition.ImportMany]
public static IProductService ProductService{ get; set; }
[System.Composition.ImportMany]
public static IProductRepository ProductRepository{ get; set; }
var executableLocation = Assembly.GetEntryAssembly().Location;
var assemblies = Directory
.GetFiles(executableLocation , "*.dll", SearchOption.TopDirectoryOnly)
.Select(AssemblyLoadContext.Default.LoadFromAssemblyPath)
.ToList();
var configuration = new ContainerConfiguration().WithAssemblies(assemblies);
using (var container = configuration.CreateContainer())
{
ProductRepository= container.GetExport<IProductRepository>();
ProductService= container.GetExport<IProductService>();
}
Here I am getting error 'No export was found for the contract 'IProductRepository"IProductService"'
My question is,
how to pass an interface to constructor of class using MEF framework?
how to pass an object to constructor of class using MEF framework?
How to implement MEF when multiple projects are involved?
After searching I have found the answer it will goes as,
The repository code should be like below
[Export(typeof(IProductRepository))]
public class ProductRepository : IProductRepository
{
[ImportingConstructor]
public ProductRepository(ApplicationDBContext context)
{
this.context = context;
}
}
The service code should be like below
[Export(typeof(IProductService))]
public class ProductService : IProductService
{
[Import(typeof(IProductRepository ))]
private IProductRepository productRepository;
[ImportingConstructor]
public ProductService(IProductRepository _ProductRepository)
{
}
}
And using System.ComponentModel.Composition DLL implement the MEF container part as below
[Import(typeof(IProductService))]
public static IProductService ProductService { get; set; }
[Import(typeof(IProductRepository))]
public static IProductRepository ProductRepository { get; set; }
var catalog = new DirectoryCatalog(GlobalVariables.ApplicationAssemblyPath, "*.dll");
container = new CompositionContainer(catalog);
ProductRepository = container.GetExportedValue<IProductRepository>();
ProductService = container.GetExportedValue<IProductService>();
Hence from the ProductRepository, ProductService we will get the instance
I have a problem as stated at the title. I am using Ninject as a Dependency Injection and my Service Locator as below:
internal class ServiceLocator
{
private static readonly IServiceLocator _serviceLocator;
static ServiceLocator()
{
_serviceLocator = new DefaultServiceLocator();
}
public static IServiceLocator Current
{
get
{
return _serviceLocator;
}
}
private class DefaultServiceLocator : IServiceLocator
{
private readonly IKernel kernel; // Ninject kernel
public DefaultServiceLocator()
{
kernel = new StandardKernel();
LoadBindings();
}
public T Get<T>()
{
try
{
return kernel.Get<T>();
}
catch (Exception hata)
{
throw hata;
}
}
private void LoadBindings()
{
kernel.Bind<IErrorDal>().To<ErrorDal>().InSingletonScope().WithConstructorArgument("connectionString", "myConnectionString");
kernel.Bind<IErrorBusinessRule>().To<ErrorBusinessRule>().InSingletonScope();
kernel.Bind<IApplicationBusinessRule>().To<ApplicationBusinessRule>().InSingletonScope();
kernel.Bind<ControlService>().To<ControlService>().InSingletonScope();
}
}
}
I have used ServiceLocator in my class ErrorService class as below:
public class ErrorService : IErrorService
{
private readonly IErrorBusinessRule _errorBusinessRule;
private readonly IApplicationBusinessRule _applicationBusinessRule;
private readonly ControlService _controlService;
public ErrorService()
{
//I am getting the error here.
this._errorBusinessRule = ServiceLocator.Current.Get<IErrorBusinessRule>();
this._controlService = ServiceLocator.Current.Get<ControlService>();
this._uygulamaIsKurali = ServiceLocator.Current.Get<IApplicationBusinessRule>();
}
}
I have got the System.TypeLoadException at the line
this._errorBusinessRule = ServiceLocator.Current.Get();
'Could not load type 'System.Runtime.Remoting.RemotingServices' from assembly 'mscorlib,
After investigation, I have pointed out that my test project type was MsTest Test Project. (.Net Core) When I choose unit test project (.NET Framework) the problem has solved.
I am attempting to add a mixin to the Jackson's ObjectMapper in a Quarkus project. I have some code that looks likes this:
#Provider
public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> {
private final ObjectMapper mapper;
public ObjectMapperContextResolver() {
this.mapper = createObjectMapper();
}
#Override
public ObjectMapper getContext(Class<?> type) {
return mapper;
}
private ObjectMapper createObjectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(MyModel.class, MyMixin.class);
return mapper;
}
}
This code worked perfectly in a Thorntail project I had. For some reason, Quarkus isn't picking this up, and the object mapper is not affected. Is there something different I have to do with the Quarkus CDI?
Updates
Apparently I was a little confused about the implementation. I should be using the Json-B api. I figured out how to change the configuration for Json-B and posted it below.
Instead of providing an ObjectMapper, you can provide a JsonbConfig so that you can customize serialization/deserialization.
Here is what I ended up using:
#Provider
public class JsonConfig implements ContextResolver<Jsonb> {
#Override
public Jsonb getContext(Class type) {
JsonbConfig config = new JsonbConfig();
config.withPropertyVisibilityStrategy(new IgnoreMethods());
return JsonbBuilder.create(config);
}
}
class IgnoreMethods implements PropertyVisibilityStrategy {
#Override
public boolean isVisible(Field field) {
return true;
}
#Override
public boolean isVisible(Method method) {
return false;
}
}
This allows you to customize your JsonbConfig. Here, mine specifically prevents access of methods for serialization/deserialization. On Quarkus with Panache, this prevents isPersistent from appearing in your JSON output.
In addition to the correct answer of #jsolum, here is a working provider which uses the fasterxml-annotations to check visibility of fields and methods:
#Provider
public class JsonConfig implements ContextResolver<Jsonb> {
#Override
public Jsonb getContext(Class aClass) {
JsonbConfig config = new JsonbConfig();
config.withPropertyVisibilityStrategy(new PropertyVisibilityStrategy() {
#Override
public boolean isVisible(Field field) {
JsonIgnore annotation = field.getAnnotation(JsonIgnore.class);
return annotation == null || !annotation.value();
}
#Override
public boolean isVisible(Method method) {
JsonIgnore annotation = method.getAnnotation(JsonIgnore.class);
return annotation == null || !annotation.value();
}
});
return JsonbBuilder.create(config);
}
}
JsonbConfig in Quarkus can be customized providing an ApplicationScoped instance of JsonbConfigCustomizer (taking #jsolum's answer into account):
#ApplicationScoped
public class JsonbFormattingConfig implements JsonbConfigCustomizer {
#Override
public void customize(JsonbConfig jsonbConfig) {
jsonbConfig.withPropertyVisibilityStrategy(new IgnoreMethods());
}
}
class IgnoreMethods implements PropertyVisibilityStrategy {
#Override
public boolean isVisible(Field field) {
return true;
}
#Override
public boolean isVisible(Method method) {
return false;
}
}
Source: https://quarkus.io/guides/rest-json#json-b
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>();