Static method is thread-safe if new instances are returned allways it gets called? - asp.net

I have the following classes:
public class SesionPasoProxy
{
private static EntitySerializer _serializer = EntitySerializer.Create();
public static string Obtener(Guid idSesion, int orden)
{
SesionPaso item = new SesionPaso();
item.Orden = orden;
item.IdSesion = idSesion;
return _serializer.ToXml(item);
}
}
public class EntitySerializer
{
private EntitySerializer(){}
public static EntitySerializer Create()
{
return EntitySerializer.Create("Test");
}
public static EntitySerializer Create(string serializationContextName)
{
EntitySerializer instance = new EntitySerializer();
instance.Name = serializationContextName;
return instance;
}
public ToXml(SesionPaso x){ return x.toString();}
}
Is that code thread-safe? SessionPasoProxy is used inside a ASP.NET WebForms aspx page. So it can get called concurrently.
As you see EntitySerializer is static but is returns new instances (not Singleton)
What do you think?
My unit testing is showing is thread.safe, but i am not sure at all.
Many thanks

In general static methods aren't more or less thread safe than instance methods.
But if they only use local variables instead of fields it's likely that they are thread-safe(of course it depends on the methods used).
In your case Create is thread-safe because it always returns a new instance and no other (static) field was used which could be accessed from different threads at the same time.
But one thing: you should make EntitySerializer.ToXml static too instead of using the same instance in Obtener. It doesn't need to be an instance method:
public static string ToXml(SesionPaso x){ return x.toString();}
Then you don't need the static field _serializer(at least not for this):
public static string Obtener(Guid idSesion, int orden)
{
SesionPaso item = new SesionPaso();
item.Orden = orden;
item.IdSesion = idSesion;
return EntitySerializer.ToXml(item);
}

Related

Better way to cache a Model

My simple repository's getAll method:
public List<ListModel> GetAllLists()
{
using (MySqlConnection connection = new MySqlConnection(this.connectionString))
{
return connection.Query<ListModel>("SELECT * FROM projectx.lists").AsList();
}
}
I'm using this class I've found here in so to handle caching:
public class CacheUtils : ICacheService
{
public TValue Get<TValue>(string cacheKey, Func<TValue> getItemCallback, double durationInMinutes = 120) where TValue : class
{
TValue item = MemoryCache.Default.Get(cacheKey) as TValue;
if (item == null)
{
Debug.WriteLine("Not cached");
item = getItemCallback();
MemoryCache.Default.Add(cacheKey, item, DateTime.Now.AddMinutes(durationInMinutes));
}
else
Debug.WriteLine("Cached!");
return item;
}
public TValue Get<TValue, TId>(string cacheKeyFormat, TId id, Func<TId, TValue> getItemCallback, double durationInMinutes = 120) where TValue : class
{
string cacheKey = string.Format(cacheKeyFormat, id);
TValue item = MemoryCache.Default.Get(cacheKey) as TValue;
if (item == null)
{
item = getItemCallback(id);
MemoryCache.Default.Add(cacheKey, item, DateTime.Now.AddMinutes(durationInMinutes));
}
return item;
}
}
Home controller:
public ActionResult Index()
{
ListRepository listRep = new ListRepository();
CacheUtils cache = new CacheUtils();
return View(cache.Get("lists", listRep.GetAllLists));
}
Question, is there a better way of handling cache than calling the helper from the controller? Ideally, it should be inside the repository method. But do I need to repeat the check for existing cache data on every single method of the repository? Ie.:
public List<ListModel> GetAllLists()
{
var lists = Cache["lists"];
if(lists == null)
{
using (MySqlConnection connection = new MySqlConnection(this.connectionString))
{
lists = connection.Query<ListModel>("SELECT * FROM projectx.lists").AsList();
}
Cache["lists"] = lists;
}
return ((List<ListModel>)lists);
}
Use a decorator pattern and don't polute business or ui with caching logic.
Wire it up with something like ninject (or poor bastards if you dont want to add a DI) I'd recommend marking it as single instance.
Benefits include:
Adding a invalidating method like void Save(ListModel) is easy to
invalidate the cache.
Your top layer and bottom layer know nothing
about the fact they have been cached.
You can also decorate again to add in logging, profiling, etc
You can also control the caching life cycle
you don't polute the controller level with caching logic
easy to remove
So something like the below would work. For how too add decorators in ninject see https://stackoverflow.com/a/8910599/1073280
public class MyHomeController
{
private readonly IListCrud _listcrud;
public MyHomeController(IListCrud listcrud)
{
_listcrud = listcrud;
}
public ActionResult Index()
{
return View(_listcrud.GetAllLists());
}
}
public interface IListCrud
{
List<ListModel> GetAllLists();
}
public class ListCrud : IListCrud
{
public List<ListModel> GetAllLists()
{
using (MySqlConnection connection = new MySqlConnection(this.connectionString))
{
return connection.Query<ListModel>("SELECT * FROM projectx.lists").AsList();
}
}
}
public class ListCrudCache : IListCrud
{
private readonly ICacheService _cache;
private readonly IListCrud _inner;
public ListCrudCache(ICacheService cache, IListCrud inner)
{
_cache = cache;
_inner = inner;
}
public List<ListModel> GetAllLists()
{
return _cache.Get("lists", _inner.GetAllLists);
}
}
Opinion: maybe just to keep the code small but be careful using select * with a ORM. if someone renames or removes a column you wont have any easy to unit test/detect failure mechanism.
In my opinion it shouldn't be in the repository, as it (to me) smells like violation or SRP. Caching should be a higher level service above the repository.
You need to think about what actually needs the benefits of the caching. If the caching is for speeding up the WEB API interface, then having it in the controller is the best way by far. If you need caching elsewhere too, consider introducing some middle layer service classes and put caching there, but I would always make it optional in some way.

Change default session provider in ASP.NET

I want to change my session proviced to statically typed - I just hate typing strings because of many many errors I do.
What technology am I using? ASP.NET MVC via EXT.NET MVC
I was trying to do that using web.config but the problem is that after add session state to it visual is not going to compile my code because of that session should be using strings as keys.
I want to use session by enums such as :
public enum SessionEnum{Model}
public class Bar{
void foo(){
Session[SessionEnum.Model] = "blah";
}
}
I am aware that I can create wrapper converting enums to strings but it's not very satisfying solution for me.
public class StorageWrapper{
public object this[SessionEnum enum]{ get{return Session[enum.toString()]}; //+set
}
What I did was create static object for base class for all of my controllers and then I was able to use it across them but after closing and opening the page again I wasn't able to get values from it. I guess I should serialize them somehow but I have no idea how.
Is there any way to do that?
EDIT
My session now looks like this :
[Serializable]
public abstract class DataWrapper<T> : HttpSessionStateBase
{
Dictionary<T, object> Dictionary { get; set; } = new Dictionary<T, object>();
public object this[T a]
{
get
{
try
{
return Dictionary[a];
}
catch
{
return null;
}
}
set { Dictionary[a] = value; }
}
}
[Serializable]
public class SessionWrapper : DataWrapper<SessionNames>
{}
public enum SessionNames { Model, Login, LastOpenedFile }
It's very simple.
Create a UserSession object which does everything you want (holds your values as enum etc), instantiate it, then put it in the session.
var US = new UserSession();
US.stuff = somestuff;
Session["UserSess"] = US
Then you can just always use Session["UserSess"].stuff;
Mmmm, wouldn't you use static const string instead of an enum?
using System.Web;
public static class SessionEnum
{
public static const string Model = "_Session_Model";
public static const string Login = "_Session_Login";
public static const string LastOpenedFile = "_Session_LastOpenedFile ";
}
class test
{
void test()
{
Session[SessionEnum.Model] = "blah";
}
}

Unity injection of an instance inside WebAPI action

I am stuck with this and I wonder what is the best way to approach this problem. I have a WebApi controller where I want to inject ICommand instance but I can know what is the instance I need once I inspect the Post request data. I'll give an example to be more clear but my question also applies to Winform events where you receive an event argument and depending of this event arg you want to have different implementation injected.
public class TestController : ApiController
{
public object Post(int id)
{
ICommand command = null;
if(id = 1)
{
command = new Id1Command();
}
else
{
command = new Id2Command();
}
return new object();
}
}
The only thing I can think of is creating a factory that accepts unity container as argument and inside that factory to call container.Resolve with named instance.
My problem with that is that I am taught that you shouldn't register or resolve outside your composition root and that is violation of the good practices (according Mark Seemann). I am looking for the best design for this problem in general.
I would use a CommandFactory and pass it to the TestController:
public class TestController : ApiController
{
private readonly ICommandFactory mCommandFactory;
public TestController(ICommandFactory CommandFactory)
{
mCommandFactory = CommandFactory;
}
public object Post(int id)
{
ICommand command = null;
if(id = 1)
{
command = CommandFactory.CreateId1Command();
}
else
{
command = CommandFactory.CreateId2Command();
}
return new object();
}
}
Now you have to make sure that Unity is creating the TestController. To do so, you have to implement, configure and set an IDependencyResolver. Check Dependency Injection in ASP.NET Web API 2.
Edit to your comment:
For this scenario you can use an autofactory using a functor that takes an int:
public class TestController : ApiController
{
private readonly Func<int, ICommand> mCommandFactory
public TestController(Func<int, ICommand> CommandFactory)
{
mCommandFactory = CommandFactory;
}
public object Post(int id)
{
var command mCommandFactory(id);
return new object();
}
}
The registration should look like this:
container.RegisterType<Func<int, ICommand>>(new InjectionFactory(
c => new Func<int, ICommand>(
id =>
{
if (id == 1)
{
return new Command();
}
else
{
return new Command2();
}
})));
Note: You still have to set the DependencyResolver!

Testable design

I have a java class which has a static member created using Facade (Singleton).
Class A implements InterfaceA {
private static DataStore db = DataStoreFacade.getInstance("BDB"); //singleton instance
public void save(final String key, final String val) {
db.save(key,val);
}
};
Here Class A is used as a member variable for webservice (stateless bean).
I can't test this code using EasyMock because there is no way to override the DataStore instance.
There are two options.
Have a constructor taking the instance of DataStore which will set to db member variable. The problem is I don't want webservice class to know which datastore instance has been created.
Provide an additional protected Set Method to override the db object. This is what I have used where I create a Easy Mock object of DataStore and override the member variable. Is it the correct design.
What are the other possibilities?
You're right that is bad for testability. Use dependency injection and don't go for static variable:
public class A implements InterfaceA {
private DataStore db;
public A(DataStore db) {
this.db = db;
}
...
}
to inject or build either use dependency-injection framework (e.g. spring) or build the object somewhere in bootstrap factory code yourself.
production code:
new A(DataStoreFacade.getInstance("...");
test-code:
public void test_xxx(){
DataStore db = EasyMock.createMock(DataStore.class);
//... do some expectations and replay(db)
InterfaceA a=new A(db);
//...
}
Well, the original code is already testable. Here is a unit test for it, using JMockit:
#Test
public void testSave(final DataStore mockDb)
{
final String key = "aKey";
final String value = "aValue";
new A().save(aKey, aValue);
new Verifications()
{{
mockDb.save(key, value);
}};
}
If needed, the DataStoreFacade class could be mocked too.
Why not make the db member protected, and in your test project inherit it and override that member:
project
{
Class A
{
protected static db = ...
public void Save(...) { ... }
}
}
test_project
{
Class B : A
{
protected override static db = ... (create test db)
}
Class testB
{
public A a;
public void Setup()
{
this.a = new B();
}
public void TearDown()
{
// delete a
}
public void TestSaveKey()
{
// test a
}
}
}
It's still hidden from consumers of the code/library, the test object isn't cluttering the production code, and the behaviour will be tested as if it were the production version.
Beware though, that having a static member for your db object could cause troubles for your tests if it's not cleaned up properly after each test.*
I know that you probably already know this, but I'm saying it for completeness.
Use the Supersede Instance pattern...
http://goodcoffeegoodcode.blogspot.com/2010/01/supercede-instance-pattern.html

Canyone explain the code written below in ActionScript

package samples.flexstore
{
import flash.events.Event;
public class ProductThumbEvent extends Event
{
public static const DETAILS:String = "details";
public static const BROWSE:String = "browse";
public var product:Product;
public function ProductThumbEvent(type:String, product:Product)
{
super(type);
this.product = product;
}
override public function clone():Event
{
return new ProductThumbEvent(type, product);
}
}
}
I need to know these things for better understanding.
What is public static const DETAILS:String = "details";
Why static keyword is used.
Why const used and what is it for.
Why does the DETAILS:String have a value details.
public var product:Product;
public function ProductThumbEvent(type:String, product:Product)
{
super(type);
this.product = product;
}
What does this constructor do?
What does super(type) do?
what does this.product = product implies?
override public function clone():Event
{
return new ProductThumbEvent(type, product);
}
What are they trying to return why can't they return in previous constructor instead of creating a clone of the above method.
Thanks.
You are asking some pretty basic questions. I would recommend going through some basic programming courses to get you started, but here are the answers to what you asked.
public static const DETAILS:String = "details";
This means declare a string that is unchangable called DETAILS that may be accessed outside my class, and without instantiating an instance first.
Static means the member can be accessed without an instance of the class being created.
so ProductThumbEvent.DETAILS is how you would access the static member DETAILS in your code.
const says that the value "details" assigned to DETAILS is constant and can not be changed.
super(type) says to call the base class (Events) constructor and pass type to it.
this.product = product says take the value passed into the product parameter and assign it to public member Product.
The purpose of the clone method is to return a new instance of the object. One could just as easily call the same constructor again if they chose (assuming they still have the proper argument data in scope), but the original author has decided to implement this method to do the task.

Resources