I'm trying to implement the singleton pattern in a database helper class, but, I can't seem to understand the purpose of a factory constructor and if there's an alternative method to using it.
class DbHelper {
final String tblName ='';
final String clmnName ='';
final String clmnPass='';
DbHelper._constr();
static final DbHelper _db = new DbHelper._constr();
factory DbHelper(){ return _db;}
Database _mydb;
Future<Database> get mydb async{
initDb() {
if(_mydb != null)
{
return _mydb;
}
_mydb = await initDb();
return _mydb;
}
There is no need to use the factory constructor.
The factory constructor was convenient when new was not yet optional because then it new MyClass() worked for classes where the constructor returned a new instance every time or where the class returned a cached instance. It was not the callers responsibility to know how and when the object was actually created.
You can change
factory DbHelper(){ return _db;}
to
DbHelper get singleton { return _db;}
and acquire the instance using
var mySingletonReference = DbHelper.singleton;
instead of
var mySingletonReference = DbHelper();
It's just a matter of preference.
I also found this article helpful: https://theburningmonk.com/2013/09/dart-implementing-the-singleton-pattern-with-factory-constructors/
Related
I have an .NET Core Web Api 2.1 app in which I only serialize the properties requested by the client.
Example: GET orders/1?select=Id,TotalAmount
Example: GET orders/1?select=Id,CustomerName,DeliveryAddress,Location,ZipCode
For that, the app creates an object in every request (Lifetime Scoped) to get the requested properties.
Then, I created Custom ContractResolver class that is instanciated in every request by a global IResultFilter:
public class SerializationFilter : IResultFilter
{
private readonly IApiQueryParameters _apiQueryParameters;
public SerializationFilter(IApiQueryParameters apiQueryParameters)
{
this._apiQueryParameters = apiQueryParameters;
}
public void OnResultExecuting(ResultExecutingContext context)
{
var objectResult = context.Result as ObjectResult;
if (objectResult != null)
{
var contractResolver = new SelectiveResourceContractResolver(this._apiQueryParameters);
var serializerSettings = new JsonSerializerSettings
{
ContractResolver = contractResolver
};
var jsonFormatter = new JsonOutputFormatter(
serializerSettings,
ArrayPool<char>.Shared);
objectResult.Formatters.Add(jsonFormatter);
}
}
}
Now, this works for the first request made after the app is online.
The second request creates the ContractResolver correctly, but the response is not correct. The returned serialized properties are not the ones requested by the client.
Debugging the code, I noticed that when the SelectiveResourceContractResolver is created, it access the constructor method right,
public SelectiveResourceContractResolver(IApiQueryParameters apiQueryParameters)
{
this._apiQueryParameters = apiQueryParameters;
}
Also, it runs the CreateProperty overriden method:
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
But in the second request, the CreatePropertyMethod is not run.
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
property.ShouldSerialize =
instance =>
{
...
};
return property;
}
The second time on, it justs executes the property.ShouldSerialize = instance => part. I think some sort of caching is done by the app, but the wierd thing is that the ContractResolver is created in every request (it´s not set globally in Startup.cs) when the filter is executed. Also, when I debug it in the second request, the property IApiQueryParameters in the ContractResolver has all the values of the first request and not from the second execution of the constructor.
What I´m missing here?
I'm assuming your SelectiveResourceContractResolver inherits from DefaultContractResolver.
DefaultContractResolver.ResolveContract, which is called internally during serialization, caches contracts in a static, thread-safe dictionary, so CreateContract (which in turn calls CreateProperty) will only be called once per type for as long as your WebAPI process runs.
This is because calling CreateContract is expensive, and not caching contracts will seriously impact serialisation performance.
If you only need to cache contracts per response, you can create your own instance cache in SelectiveResourceContractResolver and override ResolveContract to use your cache instead:
public class InstanceCachingContractResolver : DefaultContractResolver
{
private readonly Dictionary<Type, JsonContract> contractCache = new Dictionary<Type, JsonContract>();
public override JsonContract ResolveContract(Type type)
{
if (!contractCache.TryGetValue(type, out JsonContract contract))
{
contract = CreateContract(type);
contractCache.Add(type, contract);
}
return contract;
}
}
In my spring boot service, I'm using https://github.com/java-json-tools/json-patch for handling PATCH requests.
Everything seems to be ok except a way to avoid modifying immutable fields like object id's, creation_time etc. I have found a similar question on Github https://github.com/java-json-tools/json-patch/issues/21 for which I could not find the right example.
This blog seems to give some interesting solutions about validating JSON patch requests with a solution in node.js. Would be good to know if something similar in JAVA is already there.
Under many circumstances you can just patch an intermediate object which only has fields that the user can write to. After that you could quite easily map the intermediate object to your entity, using some object mapper or just manually.
The downside of this is that if you have a requirement that fields must be explicitly nullable, you won’t know if the patch object set a field to null explicitly or if it was never present in the patch.
What you can do too is abuse Optionals for this, e.g.
public class ProjectPatchDTO {
private Optional<#NotBlank String> name;
private Optional<String> description;
}
Although Optionals were not intended to be used like this, it's the most straightforward way to implement patch operations while maintaining a typed input. When the optional field is null, it was never passed from the client. When the optional is not present, that means the client has set the value to null.
Instead of receiving a JsonPatch directly from the client, define a DTO to handle the validation and then you will later convert the DTO instance to a JsonPatch.
Say you want to update a user of instance User.class, you can define a DTO such as:
public class UserDTO {
#Email(message = "The provided email is invalid")
private String username;
#Size(min = 2, max = 10, message = "firstname should have at least 2 and a maximum of 10 characters")
private String firstName;
#Size(min = 2, max = 10, message = "firstname should have at least 2 and a maximum of 10 characters")
private String lastName;
#Override
public String toString() {
return new Gson().toJson(this);
}
//getters and setters
}
The custom toString method ensures that fields that are not included in the update request are not prefilled with null values.
Your PATCH request can be as follows(For simplicity, I didn't cater for Exceptions)
#PatchMapping("/{id}")
ResponseEntity<Object> updateUser(#RequestBody #Valid UserDTO request,
#PathVariable String id) throws ParseException, IOException, JsonPatchException {
User oldUser = userRepository.findById(id);
String detailsToUpdate = request.toString();
User newUser = applyPatchToUser(detailsToUpdate, oldUser);
userRepository.save(newUser);
return userService.updateUser(request, id);
}
The following method returns the patched User which is updated above in the controller.
private User applyPatchToUser(String detailsToUpdate, User oldUser) throws IOException, JsonPatchException {
ObjectMapper objectMapper = new ObjectMapper();
// Parse the patch to JsonNode
JsonNode patchNode = objectMapper.readTree(detailsToUpdate);
// Create the patch
JsonMergePatch patch = JsonMergePatch.fromJson(patchNode);
// Convert the original object to JsonNode
JsonNode originalObjNode = objectMapper.valueToTree(oldUser);
// Apply the patch
TreeNode patchedObjNode = patch.apply(originalObjNode);
// Convert the patched node to an updated obj
return objectMapper.treeToValue(patchedObjNode, User.class);
}
Another solution would be to imperatively deserialize and validate the request body.
So your example DTO might look like this:
public class CatDto {
#NotBlank
private String name;
#Min(0)
#Max(100)
private int laziness;
#Max(3)
private int purringVolume;
}
And your controller can be something like this:
#RestController
#RequestMapping("/api/cats")
#io.swagger.v3.oas.annotations.parameters.RequestBody(
content = #Content(schema = #Schema(implementation = CatDto.class)))
// ^^ this passes your CatDto model to swagger (you must use springdoc to get it to work!)
public class CatController {
#Autowired
SmartValidator validator; // we'll use this to validate our request
#PatchMapping(path = "/{id}", consumes = "application/json")
public ResponseEntity<String> updateCat(
#PathVariable String id,
#RequestBody Map<String, Object> body
// ^^ no Valid annotation, no declarative DTO binding here!
) throws MethodArgumentNotValidException {
CatDto catDto = new CatDto();
WebDataBinder binder = new WebDataBinder(catDto);
BindingResult bindingResult = binder.getBindingResult();
binder.bind(new MutablePropertyValues(body));
// ^^ imperatively bind to DTO
body.forEach((k, v) -> validator.validateValue(CatDto.class, k, v, bindingResult));
// ^^ imperatively validate user input
if (bindingResult.hasErrors()) {
throw new MethodArgumentNotValidException(null, bindingResult);
// ^^ this can be handled by your regular exception handler
}
// Here you can do normal stuff with your cat DTO.
// Map it to cat model, send to cat service, whatever.
return ResponseEntity.ok("cat updated");
}
}
No need for Optional's, no extra dependencies, your normal validation just works, your swagger looks good. The only problem is, you don't get proper merge patch on nested objects, but in many use cases that's not even required.
I need to know how can I mock a method which uses .collect(java 8) method, below is the method
//return data
public String getData(List<Node> nodes)
{
return nodes.stream().map(node->
getService().compare(new Reference()).collect(Collectors.joining(~));
}
protected getService()
{
return service;
}
I can mock service like
#Mock //mocking service
Service service
now how can I mock
getService().compare(new Reference()).collect(Collectors.joining(~));
Compare method returns CompareRef object. I can use PowerMock.
In your case I would recommend to mock the compare() method, not collect().
Because you work with a stream you may have some nodes. To emulate the behaviour with multiply call of compare() with the same Reference object you may try this variant:
final CompareRef expectedCompareRef1 = new CompareRef();
final CompareRef expectedCompareRef2 = new CompareRef();
final CompareRef expectedCompareRef3 = new CompareRef();
when(service.compare(eq(new Reference())).thenReturn(expectedCompareRef1).thenReturn(expectedCompareRef2).thenReturn(expectedCompareRef3);
then call you getData() method:
final List<Nodes> givenNodes = new ArrayList<>();
givenNodes.add(node1);
givenNodes.add(node2);
givenNodes.add(node3);
final String actualResult = myInstance.getData(givenNodes);
Assert.assertEquals("TODO: expectedResult", actualResult);
As result the stream will collect all your test expectedCompareRefN objects.
Note, to have working eq(new Reference()) your Reference class should implement equals/hashCode methods. Otherwise eq(new Reference()) always be false and thenReturn will not return the specified expected objects.
This question already has an answer here:
Dart factory constructor - how is it different to “const” constructor
(1 answer)
Closed 8 years ago.
Below is about a usage of factory constructor from Seth Ladd's blog ' Dart - Trying to understand the value of 'factory' constructor'.
class Symbol {
final String name;
static Map<String, Symbol> _cache = new Map<String, Symbol>();
factory Symbol(String name) {
if (_cache.containsKey(name)) {
return _cache[name];
} else {
final symbol = new Symbol._internal(name);
_cache[name] = symbol;
return symbol;
}
}
Symbol._internal(this.name);
}
main() {
var x = new Symbol('X');
var alsoX = new Symbol('X');
print(identical(x, alsoX)); // true
}
IMHO, with general constructor, the same effect can be achieved with a subtle difference, but quite simpler.
class Symbol {
static final Map<String, Symbol> cache = {};
final String name;
Symbol(name) {
cache[name] = new Symbol._internal();
}
Symbol._internal();
}
main(){
var a = new Symbol('something');
var b = new Symbol('something');
print(identical(a, b)); // false!
print(Symbol.cache); //{something: Instance of 'Symbol'}
}
As shown above, though the two instances, a & b, are different objects, the effect is all the same as shown in 'print(Symbol.cache); //{something: Instance of 'Symbol'}' as a map object permit only one of same strings as its key.
So, my question was what are peculiar merits of factory constructor(or factory pattern) over general/const constructors? Because the above sample code alone shows no merit of factory constructor.
Could anyone explain what is so called 'Factory Pattern' in Dart language rather than Java/C#?
The factory PATTERN is the same. It's a general pattern and is not language specific.
Dart provides factory constructors to support the factory pattern. The factory constructor is able to return values (objects). In your first example you check if there is an instance for the key you return it.
In the second example you don't check the key of the map and you don't return the instance. That's why the two instances are not identical.
Regards,
Robert
recently I have set up a WCF restful service with EF4.
It all worked out when returning XML format response. however when it comes to JSON, I got 504 Error. unable to return json data, WCF Resful Service .NET 4.0
By digging deeper by using Service Trace Viewer:
I found this error:
'The type 'xxx.DataEntity.AppView'
cannot be serialized to JSON because
its IsReference setting is 'True'. The
JSON format does not support
references because there is no
standardized format for representing
references. To enable serialization,
disable the IsReference setting on the
type or an appropriate parent class of
the type.'
The "AppView" is a complex object class which generated by EF4 from a store procedure.
I spend quite a bit time google how to disable the IsReference, very little result so far.
anyone? with any solutions?
thanks in advance
Code:
[OperationContract]
[WebInvoke(Method = "GET",
BodyStyle = WebMessageBodyStyle.Wrapped,
UriTemplate = "App/{id}/{format}")]
AppView FuncDetail(string id, string format);
public AppView FuncDetail(string id, string format)
{
SetResponseFormat(format);
return AppSvcs.GetById(id);
}
private void SetResponseFormat(string format)
{
if (format.ToLower() == "json")
{
ResponseContext.Format = WebMessageFormat.Json;
}
else
{
ResponseContext.Format = WebMessageFormat.Xml;
}
}
I ran into exactly the same issue. It only happened on one of my service methods where I was trying to return JSON serialised Entity objects. For all my other methods I was returning JSON serialised data transfer objects (DTOs), which are stand-alone and not connected to the Entity framework. I am using DTOs for data posted into methods. Often, the data you send out does not need all the data you store in the model or the database e.g. ID values, updated dates, etc. The mapping is done in the model class, like so:
public partial class Location
{
public static LocationDto CreateLocationDto(Location location)
{
LocationDto dto = new LocationDto
{
Accuracy = location.Accuracy,
Altitude = location.Altitude,
Bearing = location.Bearing
};
return dto;
}
It may seem a bit clunky but it works and it ensures that you only send the data fields you intended to send back. It works for me because I only have 5 or 6 entities but I can see that it would get a bit tedious if you have lots of classes.
I was running into the same problem, as caused by using the auto-generated ADO Entity Models. I have not found a direct fix for this issue, but as a work around, I serialize the response as json explicitly.
So in your example, the AppView FuncDetail looks like this:
public object FuncDetail(string id, string format)
{
SetResponseFormat(format);
// where AppSvc is the object type and the enumerable list of this type is returned by the GetById method, cast it to a json string
return JSONSerializer.ToJson<AppSvc>(AppSvcs.GetById(id));
}
Here are the Serializers that I'm using:
public static class GenericSerializer
{
public static DataTable ToDataTable<T>(IEnumerable<T> varlist)
{
DataTable dtReturn = new DataTable();
// column names
PropertyInfo[] oProps = null;
if (varlist == null) return dtReturn;
foreach (T rec in varlist)
{
// Use reflection to get property names, to create table, Only first time, others will follow
if (oProps == null)
{
oProps = ((Type)rec.GetType()).GetProperties();
foreach (PropertyInfo pi in oProps)
{
Type colType = pi.PropertyType;
if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition()
== typeof(Nullable<>)))
{
colType = colType.GetGenericArguments()[0];
}
dtReturn.Columns.Add(new DataColumn(pi.Name, colType));
}
}
DataRow dr = dtReturn.NewRow();
foreach (PropertyInfo pi in oProps)
{
dr[pi.Name] = pi.GetValue(rec, null) == null ? DBNull.Value : pi.GetValue
(rec, null);
}
dtReturn.Rows.Add(dr);
}
return dtReturn;
}
}
public static class JSONSerializer
{
public static string ToJson<T>(IEnumerable<T> varlist)
{
DataTable dtReturn = GenericSerializer.ToDataTable(varlist);
return GetJSONString(dtReturn);
}
static object RowsToDictionary(this DataTable table)
{
var columns = table.Columns.Cast<DataColumn>().ToArray();
return table.Rows.Cast<DataRow>().Select(r => columns.ToDictionary(c => c.ColumnName, c => r[c]));
}
static Dictionary<string, object> ToDictionary(this DataTable table)
{
return new Dictionary<string, object>
{
{ table.TableName, table.RowsToDictionary() }
};
}
static Dictionary<string, object> ToDictionary(this DataSet data)
{
return data.Tables.Cast<DataTable>().ToDictionary(t => "Table", t => t.RowsToDictionary());
}
public static string GetJSONString(DataTable table)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
return serializer.Serialize(table.ToDictionary());
}
public static string GetJSONString(DataSet data)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
return serializer.Serialize(data.ToDictionary());
}}
It is a lot clearer to use Entity Metadata instead of Reflection.
The Metadata is pretty extensive.
another way to do this is to use LINQ to create an anonymous type with the subset of fields that you need from your entity and then use JSON.NET to serialize the collection of anon types that you created in the LINQ statement. then persist that collection out as a string by serializing.