I am trying to understand HK2 Factory implementation in Jersey Application.
Goal : How to implement singleton factory?
// Below is the simple factory implementation
public class MyFactory implements Factory<SomeObject> {
private static final Logger logger = LoggerFactory.getLogger(MyFactory.class);
private final CloseableService closeService;
#Inject
public MyFactory(CloseableService closeService) {
this.closeService = closeService;
}
#Override
public MyFactory provide() {
logger.debug("provide object from MyFactory");
SomeObject objectFromFactory = new SomeObject();
this.closeService.add(() -> dispose(objectFromFactory));
return objectFromFactory;
}
#Override
public void dispose(SomeObject instance) {
// destroy instance
logger.debug("dispose object from MyFactory");
}
}
// and binding
bindFactory(MyFactory.class).to(SomeObject.class).in(Singelton.class);
// to check object creation and destruction
bind(HK2InstanceListener.class).to(InstanceLifecycleListener.class).in(Singleton.class);
// and injecting in some resource class
#Inject
SomeObject useThisObject;
//updated information
AbstractBinder abstractBinder = configureBinder();
ServiceLocator appServiceLocator = configureHK2(abstractBinder);
public static AbstractBinder configureBinder() {
return new AbstractBinder() {
#Override
protected void configure() {
bindFactory(MyFactory.class).to(SomeObject.class).in(Singelton.class);
// to check object creation and destruction
bind(HK2InstanceListener.class).to(InstanceLifecycleListener.class).in(Singleton.class);
}
}
public ServiceLocator configureHK2(AbstractBinder binder) {
ServiceLocatorFactory factory = ServiceLocatorFactory.getInstance();
ServiceLocator locator = factory.create("my-test-server");
DynamicConfigurationService dcs = locator.getService(DynamicConfigurationService.class);
DynamicConfiguration dc = dcs.createDynamicConfiguration();
locator.inject(binder);
binder.bind(dc);
dc.commit();
return locator;
}
On starting application I see below in the logs
10:38:34.122 [grizzly-http-server-0] DEBUG com.test.HK2InstanceListener - HK2 before object create : com.test.MyFactory
10:38:34.125 [grizzly-http-server-0] DEBUG com.test.HK2InstanceListener - HK2 before object create : com.test.MyFactory
10:38:34.125 [grizzly-http-server-0] DEBUG com.test.HK2InstanceListener - HK2 after object create : com.test.MyFactory
10:38:34.125 [grizzly-http-server-0] DEBUG com.test.MyFactory provide - object from MyFactory
10:38:35.700 [grizzly-http-server-0] DEBUG com.test.HK2InstanceListener - HK2 after object create : com.test.MyFactory
10:38:37.743 [grizzly-http-server-0] DEBUG com.test.MyFactory - dispose object from MyFactory
When scope = Singleton
creating two objects of MyFactory
Next request fails with null pointer exception #Inject.
When scope = RequestScoped, PerLookup
Every request creates two objects of MyFactory
By Singleton factory, I understand is, a single object of factory (MyFactory) which provides some kind of objects upon injection.
So (1) should work or am I missing something?
And Why two objects of Factory?
Any suggestions? Thanks in advance.
HK2 Version : 2.5.0-b60
Jersey Version: 2.26
Additional Information on NPE
It was not from HK2 but behavior differs between .in(Singleton.class) and .in(PerLookup.class)
// SomeObject looks like
Class SomeObject
{
private Stack<String> someStack;
public SomeObject() {
// this may be the issue for Singleton
this.someStack = new Stack();
}
public someOperation(String stackIt)
{
// NPE location
this.someStack.push(stackIt);
}
}
NPE at above location when below
bindFactory(MyFactory.class,Singleton.class).to(SomeObject.class).in(Singleton.class);
No NPE at above location when below
bindFactory(MyFactory.class,Singleton.class).to(SomeObject.class).in(PerLookup.class);
When you do your bindFactory use the second argument to bind the Factory as a Singleton. The way you are doing it only the provide method is bound as a Singleton. So to make the Factory itself also a Singleton do it like this:
bindFactory(MyFactory.class, Singleton.class).to(SomeObject.class).in(Singelton.class);
That should get both the thing provided AND the Factory itself bound as singletons.
Related
I've been struggling with this for a long time.
For sure, what I currently know is that you should use a factory or static fromJson when you need only one object and a Constructor named .fromJson when you need to create multiple instances.
So.. when?? when we need a one instance and when we need multiple instances??
I'm creating a model class for API response right now, and I'm deeply troubled about whether to use the factory or not.
Factory constructor allows returning already created instances. It allows us easily make singletons and multitones. From the call side, it looks like the usual constructor, but from inside implementation, it varies. Also, the factory constructor doesn't force you to return only one instance (object) as you stated. You can create as many as you need. It allows returning already created instances. That's the difference with an ordinary constructor that always returns a new instance. So this feature gives us some flexibility and in some cases performance improvements.
An example:
class Logger {
static Logger _instance;
Logger._() {
print('Logger created');
}
factory Logger() {
return _instance ??= Logger._();
}
void log(String msg) => print('${DateTime.now()}: $msg');
}
void main() {
A().initialize();
B().initialize();
}
class A {
Logger _logger;
void initialize() {
_logger = Logger();
_logger.log('A initialized');
}
}
class B {
Logger _logger;
void initialize() {
_logger = Logger();
_logger.log('B initialized');
}
}
If we run this code it will produce output like that:
Logger created
2021-09-27 21:59:23.887: A initialized
2021-09-27 21:59:23.887: B initialized
Where you can see that only one instance of Logger class has been created. Despite from calling side we've requested to create two instances.
In most cases, if your task it to create a modal class for API response an ordinary constructor with a static fromJson method is enough.
In .NET Core 3 I extended ComplexTypeModelBinder class to create custom model binder for a specific class.
Main target was to override creation of model instance via CreateModel method.
public MyModelBinder: ComplexTypeModelBinder
{
// Constructor here...
protected override object CreateModel(ModelBindingContext bindingContext)
{
// Create model instance based on custom condition.
}
}
After an upgrade to .NET 5, I'm receiving a compilation warning to replace ComplexTypeModelBinder with ComplexObjectModelBinder:
warning CS0618: 'ComplexTypeModelBinder' is obsolete: 'This type is obsolete and will be removed in a future version. Use ComplexObjectModelBinder instead.'
The problem is that ComplexObjectModelBinder is sealed class and CreateModel method is internal, so subclass approach cannot work any more.
The solution I settled for is to create class MyModelBinder which implement IModelBinder interface and acts as a wrapper around ComplexObjectModelBinder. ComplexObjectModelBinder is passed in MyModelBinder as constructor parameter.
Same approach is used for MyModelBinderProvider and ComplexObjectModelProvider.
Later, instead of overriding CreateMethod of ComplexObjectModelBinder, which is not possible in .NET 5, just assign bindingContext.Model in the wrapper method BindAsyncModel of MyModelBinder, before passing the bindingContext to ComplexObjectModelBinder's BindAsyncModel. This will make ComplexObjectModelBinder use model that is passed in, instead of creating default new instance.
public class MyModelBinder: IModelBinder
{
private readonly ComplexObjectModelBinder _binder;
public MyModelBinder(ComplexObjectModelBinder binder)
{
_binder = binder;
}
public Task BindModelAsync(ModelBindingContext bindingContext)
{
MyModel myModel = // custom instantiation logic here
bindingContext.Model = myModel;
return _binder.BindModelAsync(bindingContext);
}
}
For the registration of the custom model binder provider, first we find existing, automatically registered ComplexObjectBinderProvider, use it in costructor of MyModelBinderProvider and then insert MyModelBinderProvider in front of ComplexObjectBinderProvider.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews(options => {
// more configurations here...
var bindingProvider = options.ModelBinderProviders.First(provider =>
provider is ComplexObjectModelBinderProvider) as ComplexObjectModelBinderProvider;
var indexOf = options.ModelBinderProviders.IndexOf(bindingProvider);
options.ModelBinderProviders.Insert(indexOf, new MyModelBinderProvider(bindingProvider));
}
}
I have this class to be instantiated in a unittest:
public class Customer
{
internal Customer(Guid id) {
// initialize property
}
}
If I instantiate the test class from another (unittests) assembly with a new Customer() works because I added [assembly: InternalsVisibleTo("MyProject.Tests")]
var sut = new Customer(Guid.NewGuid()); // works
But when i setup an autofac container in the other (unittest) assembly
var builder = new ContainerBuilder();
builder.RegisterType<Customer>().AsSelf();
var container = builder.Build();
I can't resolve with autofac.
var theParam = new NamedParameter("id", Guid.NewGuid());
_sut = container.Resolve<Customer>(theParam); // throws exception
My best guess was that the internal constructor was not available. But adding [assembly: InternalsVisibleTo("Autofac")] next to the other doesn't help.
The exception thown by Autofac is
Autofac.Core.DependencyResolutionException:
An error occurred during the activation of a particular registration. See the inner exception for details.
Registration: Activator = Customer (ReflectionActivator),
Services = [MyProject.Customer],
Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime,
Sharing = None,
Ownership = OwnedByLifetimeScope
---> No accessible constructors were found for the type 'MyProject.Customer'.
Can Autofac not handle internal constructors?
Autofac can't locate non-public constructors because it uses the DefaultConstructorFinder class which searches only for public constructors by default.
You have to create your custom implementation of the IConstructorFinder interface like this:
public class AllConstructorFinder : IConstructorFinder
{
private static readonly ConcurrentDictionary<Type, ConstructorInfo[]> Cache =
new ConcurrentDictionary<Type, ConstructorInfo[]>();
public ConstructorInfo[] FindConstructors(Type targetType)
{
var result = Cache.GetOrAdd(targetType,
t => t.GetTypeInfo().DeclaredConstructors.Where(c => !c.IsStatic).ToArray());
return result.Length > 0 ? result : throw new NoConstructorsFoundException(targetType);
}
}
Then you have to use the FindConstructorsWith extension method on type registration:
builder.RegisterType<Customer>()
.FindConstructorsWith(new AllConstructorFinder())
.AsSelf();
The InternalsVisibleToAttribute can't help in this case because it affects only the compile time.
if you want to register assembly types with at least only has one public constructor then you can use Autofac Where extension method like this.
builder.RegisterAssemblyTypes(assembly)
.Where(t => t.GetConstructors().Length > 0) //only public constructors
.AsImplementedInterfaces()
.InstancePerLifetimeScope();
Note: PublicOnly extension method registers only public types.
I've got a Factory interface (along with concrete implementations):
// foo.dll
interface IFooProvider
{
T GetFoo<T>()
where T : BaseFoo;
}
My BaseFoo is not abstract, but only its subclasses are actually useful:
// shared.dll
class BaseFoo
{ ... }
I've also got a (potentially unbounded) number of subclasses of BaseFoo across many assemblies:
// foo.dll
class AFoo : BaseFoo
{ ... }
// foo2.dll
class BFoo : BaseFoo
{ ... }
... and many more ...
Naively, I had been registering the Foo-derived classes in an unsurprising way:
// foo.dll
class ConcreteFooRegistration : Module
{
protected override void Load(ContainerBuilder builder)
{
// a concrete FooProvider is registered elsewhere
builder.Register(c => c.Resolve<IFooProvider>().GetFoo<AFoo>());
builder.Register(c => c.Resolve<IFooProvider>().GetFoo<BFoo>());
...
}
}
But this implies that:
the assembly containing ConcreteFooRegistration (e.g. foo.dll) also contains some/all of AFoo, BFoo, etc.
the assembly containing ConcreteFooRegistration (e.g. foo.dll) references the assemblies (e.g. foo2.dll) containing some/all of AFoo, BFoo, etc.
IFooProvider be available to any other assembly containing BaseFoo-derived classes and the Module that registers them
For sake of discussion, assume that none of these is possible and/or desirable. That is, I'm looking for solutions other than "move IFooProvider into shared.dll".
Since AFoo and BFoo are the real dependencies that other types are interested in, and IFooProvider is (from that perspective) just an instantiation detail, I got inspired by the Autofac+Serilog integration that Nicholas came up with. I've used a similar approach elsewhere, so I wrote up an AttachToComponentRegistration() implementation:
// foo.dll
class ConcreteFooRegistration : Module
{
// NOTICE: there's no Load() method
protected override void AttachToComponentRegistration(...)
{
...
registration.Preparing += (sender, e) =>
{
var pFoo = new ResolvedParameter(
(p, i) => p.ParameterType.IsAssignableTo<BaseFoo>(),
(p, i) => i.Resolve<IFooProvider>().GetFoo<FooWeNeed>()
);
e.Parameters = new [] { pFoo }.Concat(e.Parameters);
};
}
}
This was successful, in that I was able to remove all the individual BaseFoo-derived registrations from ConcreteFooRegistration and still successfully resolve arbitrary BaseFoo-derived dependencies with constructor injection:
// other.dll:
class WorkerRegisteration : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<Worker>();
// NOTICE: FooYouDidntKnowAbout is NOT explicitly registered
}
}
class Worker
{
public Worker(FooYouDidntKnowAbout foo)
{ ... }
...
}
BUT: now I can't arbitrarily resolve AFoo outside of constructor injection:
builder.Register(c =>
{
// here's one use for a BaseFoo outside constructor injection
var foo = c.Resolve<AFoo>();
if (foo.PropValue1)
return new OtherClass(foo.PropValue2);
else
return new YetAnother(foo.PropValue3);
}
...
builder.Register(c =>
{
// here's another
var foo = c.Resolve<AFoo>();
return c.Resolve(foo.TypePropValue);
});
Assuming that publishing IFooProvider as a public export of foo.dll or moving it to shared.dll is undesirable/impossible, thus eliminating the naive-but-unsurprising implementation above, (how) can I set up my registrations to be able to resolve arbitrary subclasses of BaseFoo from anywhere?
Thanks!
I think what you're looking for is a registration source. A registration source is a dynamic "registration provider" you can use to feed Autofac registrations as needed.
As of this writing, the doc on registration sources is pretty thin (I just haven't gotten a chance to write it) but there's a blog article with some details about it.
Registration sources are how Autofac supports things like IEnumerable<T> or Lazy<T> - we don't require you actually register every collection, instead we dynamically feed the registrations into the container using sources.
Anyway, let me write you up a sample here and maybe I can use it later to massage it into the docs, eh? :)
First, let's define a very simple factory and implementation. I'm going to use "Service" instead of "Foo" here because my brain stumbles after it sees "foo" too many times. That's a "me" thing. But I digress.
public interface IServiceProvider
{
T GetService<T>() where T : BaseService;
}
public class ServiceProvider : IServiceProvider
{
public T GetService<T>() where T : BaseService
{
return (T)Activator.CreateInstance(typeof(T));
}
}
OK, now let's make the service types. Obviously for this sample all the types are sort of in one assembly, but when your code references the type and the JIT brings it in from some other assembly, it'll work just the same. Don't worry about cross-assembly stuff for this.
public abstract class BaseService { }
public class ServiceA : BaseService { }
public class ServiceB : BaseService { }
Finally, a couple of classes that consume the services, just so we can see it working.
public class ConsumerA
{
public ConsumerA(ServiceA service)
{
Console.WriteLine("ConsumerA: {0}", service.GetType());
}
}
public class ConsumerB
{
public ConsumerB(ServiceB service)
{
Console.WriteLine("ConsumerB: {0}", service.GetType());
}
}
Good.
Here's the important bit, now: the registration source. The registration source is where you will:
Determine if the resolve operation is asking for a BaseService type or not. If it's not, then you can't handle it so you'll bail.
Build up the dynamic registration for the specific type of BaseService derivative being requested, which will include the lambda that invokes the provider/factory to get the instance.
Return the dynamic registration to the resolve operation so it can do the work.
It looks like this:
using Autofac;
using Autofac.Core;
using Autofac.Core.Activators.Delegate;
using Autofac.Core.Lifetime;
using Autofac.Core.Registration;
public class ServiceRegistrationSource : IRegistrationSource
{
public IEnumerable<IComponentRegistration> RegistrationsFor(
Service service,
Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor)
{
var swt = service as IServiceWithType;
if(swt == null || !typeof(BaseService).IsAssignableFrom(swt.ServiceType))
{
// It's not a request for the base service type, so skip it.
return Enumerable.Empty<IComponentRegistration>();
}
// This is where the magic happens!
var registration = new ComponentRegistration(
Guid.NewGuid(),
new DelegateActivator(swt.ServiceType, (c, p) =>
{
// The factory method is generic, but we're working
// at a reflection level, so there's a bit of crazy
// to deal with.
var provider = c.Resolve<IServiceProvider>();
var method = provider.GetType().GetMethod("GetService").MakeGenericMethod(swt.ServiceType);
return method.Invoke(provider, null);
}),
new CurrentScopeLifetime(),
InstanceSharing.None,
InstanceOwnership.OwnedByLifetimeScope,
new [] { service },
new Dictionary<string, object>());
return new IComponentRegistration[] { registration };
}
public bool IsAdapterForIndividualComponents { get{ return false; } }
}
It looks complex, but it's not too bad.
The last step is to get the factory registered as well as the registration source. For my sample, I put those in an Autofac module so they're both registered together - it doesn't make sense to have one without the other.
public class ServiceProviderModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<ServiceProvider>().As<IServiceProvider>();
builder.RegisterSource(new ServiceRegistrationSource());
}
}
Finally, let's see it in action. If I throw this code into a console app...
static void Main()
{
var builder = new ContainerBuilder();
builder.RegisterType<ConsumerA>();
builder.RegisterType<ConsumerB>();
builder.RegisterModule<ServiceProviderModule>();
var container = builder.Build();
using(var scope = container.BeginLifetimeScope())
{
var a = scope.Resolve<ConsumerA>();
var b = scope.Resolve<ConsumerB>();
}
}
What you end up with on the console is:
ConsumerA: ServiceA
ConsumerB: ServiceB
Note I had to register my consuming classes but I didn't explicitly register any of the BaseService-derived classes - that was all done by the registration source.
If you want to see more registration source samples, check out the Autofac source, particularly under the Autofac.Features namespace. There you'll find things like the CollectionRegistrationSource, which is responsible for handling IEnumerable<T> support.
I want to mock a Class in Mockito. It will then have a .newInstance() call issued which will be expected to return an actual class instance (and will return a mock in my case).
If it was setup correctly then I could do:
ArrayList myListMock = mock(ArrayList.class);
when(myVar.newInstance()).thenReturn(myListMock);
I know I can set it up so that a new instance of class ArrayList will be a mock (using PowerMockito whenNew), just wondering if there was a way to mock this kind of a class object so I don't have to override instance creation...
Below is the real class I'm trying to mock, I can't change the structure it is defined by the interface. What I'm looking for is a way to provide cvs when initialize is called.
public class InputConstraintValidator
implements ConstraintValidator<InputValidation, StringWrapper> {
Class<? extends SafeString> cvs;
public void initialize(InputValidation constraintAnnotation) {
cvs = constraintAnnotation.inputValidator();
}
public boolean isValid(StringWrapper value,
ConstraintValidatorContext context) {
SafeString instance;
try {
instance = cvs.newInstance();
} catch (InstantiationException e) {
return false;
} catch (IllegalAccessException e) {
return false;
}
}
Mockito is designed exclusively for mocking instances of objects. Under the hood, the mock method actually creates a proxy that receives calls to all non-final methods, and logs and stubs those calls as needed. There's no good way to use Mockito to replace a function on the Class object itself. This leaves you with a few options:
I don't have experience with PowerMock but it seems it's designed for mocking static methods.
In dependency-injection style, make your static factory method into a factory instance. Since it looks like you're not actually working with ArrayList, let's say your class is FooBar instead:
class FooBar {
static class Factory {
static FooBar instance;
FooBar getInstance() {
if (instance == null) {
instance = new FooBar();
}
return instance;
}
}
// ...
}
Now your class user can receive a new FooBar.Factory() parameter, which creates your real FooBar in singleton style (hopefully better and more threadsafe than my simple implementation), and you can use pure Mockito to mock the Factory. If this looks like it's a lot of boilerplate, it's because it is, but if you are thinking of switching to a DI solution like Guice you can cut down a lot of it.
Consider making a field or method package-private or protected and documenting that it's visible for testing purposes. Then you can insert a mocked instance in test code only.
public class InputConstraintValidator implements
ConstraintValidator<InputValidation, StringWrapper> {
Class<? extends SafeString> cvs;
public void initialize(InputValidation constraintAnnotation) {
cvs = constraintAnnotation.inputValidator();
}
public boolean isValid(StringWrapper value,
ConstraintValidatorContext context) {
SafeString instance;
try {
instance = getCvsInstance();
} catch (InstantiationException e) {
return false;
} catch (IllegalAccessException e) {
return false;
}
}
#VisibleForTesting protected getCvsInstance()
throws InstantiationException, IllegalAccessException {
return cvs.newInstance();
}
}
public class InputConstaintValidatorTest {
#Test public void testWithMockCvs() {
final SafeString cvs = mock(SafeString.class);
InputConstraintValidator validator = new InputConstraintValidator() {
#Override protected getCvsInstance() {
return cvs;
}
}
// test
}
}
I think you just need to introduce an additional mock for Class:
ArrayList<?> myListMock = mock(ArrayList.class);
Class<ArrayList> clazz = mock(Class.class);
when(clazz.newInstance()).thenReturn(myListMock);
Of course the trick is making sure your mocked clazz.newInstance() doesn't end up getting called all over the place because due to type-erasure you can't specify that it's actually a Class<ArrayList>.
Also, be careful defining your own mock for something as fundamental as ArrayList - generally I'd use a "real one" and populate it with mocks.