Just have a question regarding PetaPoco generated Database.cs code from version 4.0.3. See below code snippet:
public partial class postgresqlDB : Database
{
public postgresqlDB()
: base("postgresql")
{
CommonConstruct();
}
public postgresqlDB(string connectionStringName)
: base(connectionStringName)
{
CommonConstruct();
}
partial void CommonConstruct();
public interface IFactory
{
postgresqlDB GetInstance();
}
public static IFactory Factory { get; set; }
public static postgresqlDB GetInstance()
{
if (_instance!=null)
return _instance;
if (Factory!=null)
return Factory.GetInstance();
else
return new postgresqlDB();
}
[ThreadStatic] static postgresqlDB _instance;
public override void OnBeginTransaction()
{
if (_instance==null)
_instance=this;
}
public override void OnEndTransaction()
{
if (_instance==this)
_instance=null;
}
.....
..... <snip />
Looking at the GetInstance()
function, why is it that the return new postgresqlDB()
is never assigned to the private variable _instance
?
Doesn't this mean every call to GetInstance()
will always create a new instance because if (_instance != null) return _instance;
will never be true?
Thanks all for the help.
I ran into this behavior today as well with PetaPoco. (Hat's off to the creator(s) since it is generally a pleasure to use!). In a related situation, I wanted to pull a copy of the most recent sql passed through PetaPoco in order to review it with code like:
Console.WriteLine(RepositoryTableClass.repo.LastCommand);
In my case it was always empty for exactly the reason as OP suggests. The threadstatic marker is orthogonal to the original question. The only place in code where the _instance variable is set is for the duration of a transaction. As a result each instance of the repository is used and abandoned by default. (This may be to avoid problems with re-using the single connection for multiple overlapping queries\results?)
In any case the factory pattern is available and can be used to force reliance on a single repo instance if that is what you desire. Try a super simple factory class like:
private class RepoFactory : postgresqlDB.IFactory
{
private static postgresqlDB repo = postgresqlDB.GetInstance();
public postgresqlDB GetInstance()
{
return repo;
}
}
Set the factory before you begin using any repository objects like so:
postgresqlDB.Factory = new RepoFactory();
That enabled me to use repository objects against a single repository instance as verified by having a populated value for the last command after each usage...
RepositoryTableClass.repo.LastCommand