Need to be able to #Inject Serializable Set into #SessionScoped bean - serialization

I've got a producer method that wants to produce a set that is unmodifiable:
// EnumSet.noneof returns an object of type Serializable, and also
// Collections#synchronizedSet javadoc says, "The returned set will be
// serializable if the specified set is serializable."
private final Set<Role> roles =
Collections.synchronizedSet(EnumSet.noneOf(Role.class));
...
#Produces #LoggedIn public Set<Role> getRoles()
{
// Collections#unmodifiableSet javadoc also says, "The returned set will be
// serializable if the specified set is serializable."
return Collections.unmodifiableSet(this.roles);
}
I want to inject the set into a session scoped bean:
#Inject #LoggedIn Set<Role> roles;
At the injection point a warning is issued, saying that I cannot inject a set, which is not serializable, into a bean of passivating scope. The warning makes sense because the Set interfaces does not extend Serializable. However, in this circumstance it would appear, according to the javadoc, that roles is in fact serializable. I am not sure of the best way to handle this situation in order to avoid the warning.
Incidentally, I've noticed that applying #SuppressWarnings({"NonSerializableFieldInSerializableClass"}) at the injection point does not suppress the warning. But what I've also noticed that the following line of code in the same session scoped bean, located right next to the injection point, does NOT cause a warning message to be issued:
#Inject #LoggedIn Set<Role> roles; // warning
private Set<Role> roles1; // no warning!
Weird!
I have three questions:
What would be the best approach to take in this circumstance?
Why does #Inject #LoggedIn Set<Role> roles cause a warning whereas private Set<Role> roles1 does not?
Why does applying #SuppressWarnings({"NonSerializableFieldInSerializableClass"}) at the injection point not suppress the warning?

Only the first line is an injection point, hence CDI will scan it and ensure that it can be injected. The second line is not scanned by CDI to ensure that it's injectable, because CDI isn't trying to inject into it.
SuppressWarnings is a compile time annotation, not a runtime. It's lost in the compiled class.
You can create a Set implementation that implements serializable and use that. It should be injected as that set impl.

Related

Invalidating Cached Data and Dependency Injection Pattern

I have a data cache class (that uses the MemoryCache class).
The basic function of this class is to cache reference data. To get this reference data it needs an instance of an Entity Framework dbContext. This gets passed in by dependency injection (Simple Injector).
But this dbContext has a lifecycle of "per call" (AsyncScopedLifestyle). So to satisify this I put the call to setup the cache in a "scope" that expires after the call.
The cache gets invalidated every 2 hours and is re-queried. Unsurprisingly, the dbContext has been cleaned up by then (because it went out of the scope).
I can think of ways to get around this issue. But I want to know if there is a pattern I should be following for this kind of issue. (Most of my solutions have me passing the container into my cache class. But that seems to be a violation of several DI patterns.)
Anyone know of a design pattern to use when you have a reoccurring need for an injection inside of a class?
A bit more background:
My cache class (called DataCache) gets the context from constructor injection.
The call to set it up is made from the Configure method in Startup.cs. This looks like this:
.
using (AsyncScopedLifestyle.BeginScope(container))
{
// Setup the long lived data caching
var dataCache = container.GetInstance<DataCache>();
dataCache.SetupCachedItems();
}
It sets the MemoryCache to expire the data in the cache after two hours. But the injected context is long cleaned up by then.
I see two general solutions here:
Move the cache that the DataCache manages out of that class, in such way that MyCacheClass can become Scoped. This seams a no-brainer as this is likely what MemoryCache is for. Memory cache is likely a Singleton.
Move DataCache into the Composition Root so it can safely depend on the container (or a container abstraction), without falling into Service Locator anti-pattern trap.
The first solution can be applied in multiple ways. Perhaps it's a matter of defining the cache in a static field:
public class DataCache
{
private static ConcurrentDictionary<string, object> cache;
}
And in case you inject MemoryCache as storage provider for your data, it will contain the cache, and the lifestyle of DataCache becomes irrelevant:
public class DataCache
{
public DataCache(MyContext context, IMemoryCache cache)
}
If, however, DataCache needs to be injected into Singleton consumers, it itself needs to be Singleton. This disallows this approach, as MyContext needs to be Scoped, to prevent Captive Dependencies. For that you can use solution 2.
With solution to, you ensure that DataCache is created inside your Composition Root. This forces you to hide DataCache behind an abstraction, e.g. IDataCache. This abstraction can be placed in a location that allows consumers to depend on, while the DataCache implementation will be completely hidden inside the Composition Root. At that location it becomes safe to depend on the DI Container.
// Part of the Composition Root
sealed class DataCache: IDataCache
{
public DataCache(Container container, IMemoryCache cache) ...
public ProductData GetProductByKey(string key)
{
if (key not in cache)
{
using (AsyncScopedLifestyle.BeginScope(this.container))
{
var context = container.GetInstance<MyContext>();
var p = context.Products.SingleOrDefault(p => p.Key == key);
var data = new ProductData(p);
AddProductToCache(key, data);
return data;
}
}
}
}
You should rely on DI the whole way. In other words, if the cache class needs the context, then that's a dependency, and should be injected as such:
public class MyCacheClass
{
private readonly MyContext _context;
public MyCacheClass(MyContext context)
{
_context = context;
}
...
}
That of course assumes the cache class has a scoped lifetime as well, which there's really no reason it shouldn't, since it interacts with scoped dependencies. However, if for some reason you need it to have a singleton lifetime, then you can simply inject IServiceProvider and then create a scope and pull out the context when you need it:
using (var scope = _serviceProvider.CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<MyContext>();
// do something with context
}
If you're using a static class, don't.

How to bind Ninject to [Obsolete] constructor?

In my submodule, I have:
public class CustomerRepository : ICustomerRepository
{
private readonly IDBEngine _dbEngine;
[CanBeNull] private readonly string _overriddenDebugEmail;
[Obsolete("Use the other constructor")]
public CustomerRepository(IDBEngine dbEngine)
{
_dbEngine = dbEngine;
_overriddenDebugEmail = null;
}
// ReSharper disable once UnusedMember.Global
public CustomerRepository(IDBEngine dbEngine, IDebugConstants debugConstants)
{
_dbEngine = dbEngine;
_overriddenDebugEmail = debugConstants.OverridingDebugEmail;
}
...
The problem is, when I simply update the submodule without implementing IDebugConstants, I get the following runtime error:
Error activating IDebugConstants
No matching bindings are available, and the type is not self-bindable.
I want Ninject to bind to the Obsolete constructor if IDebugConstants is not implemented. But it refuses to because of the obsolete attribute.
In theory I could remove the Obsolete attribute, but I want it to show that that code should no longer exist once all old programs using the submodule have been updated.
Is there some way to make Ninject ignore the Obsolete attribute?
Or am I going about this entirely wrong somehow?
You can do this by adding the [Inject] attribute to your [Obsolete] constructor.
The reason for this is how the constructor scoring is implemented. Specifically this section of the Score method:
if (directive.Constructor.HasAttribute(this.settings.InjectAttribute))
{
return int.MaxValue;
}
if (directive.Constructor.HasAttribute(typeof(ObsoleteAttribute)))
{
return int.MinValue;
}
You will see that if the constructor has the [Obsolete] attribute then it is given the minimum possible score. But prior to that, if the constructor has the [Inject] attribute then it will be given the highest possible score.
This doesn't help in the specific case you mentioned where you want a conditional binding when IDebugConstants is not implemented, but it does answer "Is there some way to make Ninject ignore the Obsolete attribute?"

When should we use #InjectMocks?

I have read through a lot of discussion about #Mock & #InjectMocks and still could not find what are the suitable or necessary cases to use #InjectMocks. In fact, I am not sure about what would happen when we use #InjectMocks.
Consider the following example,
public class User {
private String user_name;
private int user_id;
public User(int user_id) {
this.user_id = user_id;
}
public String getUser_name() {
return user_name;
}
public void setUser_name(String user_name) {
this.user_name = user_name;
}
public int getUser_id() {
return user_id;
}
public void setUser_id(int user_id) {
this.user_id = user_id;
}
}
public interface UserDao {
public List<User> getUserList();
}
public class UserService {
private UserDao userDao;
public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public List<User> getUserList() {
return userDao.getUserList();
}
}
This is my test class
#RunWith(MockitoJUnitRunner.class)
public class UserServiceTest {
private UserService service = new UserService();
#Mock
private UserDao dao;
#Test
public void testGetUserList() {
service.setUserDao(dao);
// mock the return value of the mock object
List<User> mockResult = Arrays.asList(new User(101),new User(102),new User(103));
when(dao.getUserList()).thenReturn(mockResult);
// check return value is same as mocked value
assertEquals(service.getUserList(),mockResult);
// verify the getUserList() function is called
verify(dao).getUserList();
}
}
The test run successfully with no errors.
Consider another approach using #InjectMock annotation.
#RunWith(MockitoJUnitRunner.class)
public class UserServiceTest {
#InjectMocks
private UserService service;
#Mock
private UserDao dao;
#Test
public void testGetUserList() {
service.setUserDao(dao);
// mock the return value of the mock object
List<User> mockResult = Arrays.asList(new User(101),new User(102),new User(103));
when(dao.getUserList()).thenReturn(mockResult);
// check return value is same as mocked value
assertEquals(service.getUserList(),mockResult);
// verify the getUserList() function is called
verify(dao).getUserList();
}
}
This works equally well. So, which way is better? Any best practice?
Btw, I am using Junit 4.8.1 and Mockito 1.9.5
Your actual question can't be answered without you providing further code (the code you are showing does not explain the results you claim to observe).
Regarding the underlying question: you probably should not use #InjectMocks; one of its core problems is: if injecting fails, Mockito does not report an error to you.
In other words: you have passing unit tests, and some internal detail about a field changes ... and your unit tests break; but you have no idea why ... because the mocking framework doesn't tell you that the "initial" step of pushing a mock into the class under test is all of a sudden failing. See here for further reading.
But to be clear here: in the end, this almost a pure style question. People used to #InjectMocks will love it; other people do object it. Meaning: there is no clear evidence whether you should use this concept. Instead: you study the concept, you understand the concept, and then you (and the team working with you) make a conscious decision whether you want to use this annotation, or not.
Edit: I think I get your problem now. The idea of #InjectMocks is to inject a mocked object into some object under test.
But: you are doing that manually in both cases:
service.setUserDao(dao);
Meaning: if injecting works correctly (and there isn't a problem that isn't reported by Mockito) then your example that uses that annotation should also work when you remove that one line. Whereas the testcase that doesn't have #InjectMocks should fail without that line!
In other words: your testcases are both passing because your code does a "manual inject"!
When should we use #InjectMocks?
IHMO : we should not use it.
That favors so many design issues that I would like to add my POV on the question.
Here is relevant information from the javadoc (emphasis is not mine) :
Mark a field on which injection should be performed.
Allows shorthand mock and spy injection.
Minimizes repetitive mock and spy injection.
Mockito will try to inject mocks only either by constructor injection,
setter injection, or property injection in order and as described
below. If any of the following strategy fail, then Mockito won't
report failure; i.e. you will have to provide dependencies yourself.
...
Mockito is not an dependency injection framework,
In two words :
Advantage : you write less code to setup your mock dependencies.
Drawback : no failure if some mocks were not be set in the object under test.
IHMO the advantage hides also another drawback still more serious.
About the advantage :
Mockito uses constructor/setter/reflection to set the mocks in the object under test. The problem is that it is up to you to decide the way to set your fields : mockito will try one after the other way.
The setter way is often very verbose and provides mutability of the dependencies. So developers don't use it frequently. It makes sense.
The constructor way to set the bean dependencies requires to keep a good design with a decent number of dependencies : not more than 4 or 5 in general.
It demands strong design exigencies.
At last, the reflection way is the most easy : few code to write and no mutability of the dependencies.
The reflection way being the simplest from the lambda developer PVO, I saw many teams not aware of the consequences of reflection to specify dependencies and abuse of the reflection way in their Mockito tests but also in their design since finally InjectMocks allows to cope with it in a someway.
You may consider it fine to not finish with a class that declares 30 setters as dependencies or a constructor with 30 arguments but that has also a strong drawback : it favors bad smells such as dependency field hiding and declaration of many dependencies in as field instances of the class. As a result your class is complex, bloat, hard to read, hard to test and error prone to maintain.
The real thing is that in the very most of cases, the right solution is the constructor injection that promotes decent class responsibility and so good maintainability and testability of that.
About the drawback :
Mock injection doesn't work as the dependency injection of IOCs.
The javadoc states itself :
Mockito is not an dependency injection framework,
IOC and DI framework are able and by default consider dependencies as required. So any missing dependency will provoke a fast-fail error at the startup.
It prevents so many headaches and makes you win a precious time.
While Mockito injection will silently ignore the mocks that were not managed to be injected. It is so up to you to guess the error cause.
Finding the issue cause is sometimes complex because you don't have any clue from Mockito and that all is done by reflection by Mockito.
Using #InjectMocks injects the mocked objects as dependencies to the created object(The object marked by #InjectMocks). Creating an object using constructor will defy the purpose since the mocked objects are not injected and hence all the external calls from SUT takes place on concrete objects.Try to avoid creating SUT object by constructor call.

HttpContextBase.Request exception when using Ninject MVC3

I have a service that takes a dependency on HttpContextBase.
Ninject is injecting this for me already as it's set up in the MvcModule to return new HttpContextWrapper(HttpContext.Current) when HttpContextBase is requested
I want to use this service in Application_AuthenticateRequest, so i'm using property injection so that Ninject resolves it for me
When I try and access Request.UserHostAddress on the HttpContextBase I get a Value does not fall within the expected range exception
If I call HttpContext.Current.Request.UserHostAddress directly it works without problems
ExampleService.cs
public class ExampleService : IExampleService {
HttpContextBase _contextBase;
public ExampleService(HttpContextBase contextBase) {
_contextBase = contextBase;
}
public void DoSomething() {
var ip = HttpContext.Current.Request.UserHostAddress; <== this works
ip = _contextBase.Request.UserHostAddress; <== this fails
}
}
Global.asax
[Inject]
public IExampleService ExampleService { get; set; }
public void Application_AuthenticateRequest() {
ExampleService.DoSomething();
}
I'm missing something here, but I can't see what
Dependencies that are injected into classes live as long as the the class they get injected into, because the class holds a reference to them. This means that in general you should prevent injecting dependencies that are configured with a lifetime that is shorter than the containing class, since otherwise their lifetime is 'promoted' which can cause all sorts of (often hard to track) bugs.
In the case of an ASP.NET application, there is always just one HttpApplication instance that lives as long as the AppDomain lives. So what happens here is that the injected ExampleService gets promoted to one-per-appdomain (or singleton) and since the ExampleService sticks around, so does its dependency, the HttpContextBase.
The problem here of course is that an HTTP context -per definition- can't outlive a HTTP request. So you're storing a single HttpContextBase once, but it gets reused for all other requests. Fortunately ASP.NET throws an exception, otherwise you would probably be in much more trouble. Unfortunately the exception isn't very expressive. They could have done better in this case.
The solution is to not inject dependencies in your HttpApplication / MvcApplication. Ever! Although it's fine to do so when you're injecting singletons that only depend on singletons recursively, it is easy to do this wrong, and there's no verification mechanism in Ninject that signals you about this error.
Instead, always resolve IExampleService on each call to AuthenticateRequest. This ensures that you get an ExampleService with the right lifetime (hopefully configured as per-web-request or shorter) and prevents this kind of error. You can either call into the DependencyResolver class to fetch an IExampleService or call directly into the Ninject Kernel. Calling into the Kernel is fine, since the Application_AuthenticateRequest can be considered part of the Composition Root:
public void Application_AuthenticateRequest() {
var service = DependencyResolver.Current.GetService<IExampleService>();
service.DoSomething();
}

Stub generation failes with obsolete attribute, Pex v0.94.51023.0

I have an interface with a method marked with the obsolete attribute. The attributes error parameter is set to true to throw an exception when used. The problem is this causes the stub to not generate for the whole class. When I alter the value to false the stub generates as expected.
I’m looking for a way to generate the stub while retaining the error parameter as true.
public interface ICar
{
void Start();
[Obsolete("this is obsolete Stop, stop using it", true)]
void Stop();
}
I’ve tried different permutations of.
<Moles xmlns="http://schemas.microsoft.com/moles/2010/">
<Assembly Name="My.Car.Services"/>
<StubGeneration>
<TypeFilter TypeName="ICar" SkipObsolete="true" />
</StubGeneration>
</Moles>
This is by design. When a method is marked at Obsolete(..., true), C# will not allow to instantiate an class implementing that interface.