Comments (19)
This resolve it. Should I make a pull request?
/// <summary>
/// A factory that lazy instantiates a type and always returns the same instance
/// </summary>
private class SingletonFactory : ObjectFactoryBase, IDisposable
{
private readonly Type registerType;
private readonly Type registerImplementation;
private readonly object SingletonLock = new object();
private Dictionary<int, object> _Current = new Dictionary<int, object>();
public SingletonFactory(Type registerType, Type registerImplementation)
{
//#if NETFX_CORE
// if (registerImplementation.GetTypeInfo().IsAbstract() || registerImplementation.GetTypeInfo().IsInterface())
//#else
if (registerImplementation.IsAbstract() || registerImplementation.IsInterface())
//#endif
throw new TinyIoCRegistrationTypeException(registerImplementation, "SingletonFactory");
if (!IsValidAssignment(registerType, registerImplementation))
throw new TinyIoCRegistrationTypeException(registerImplementation, "SingletonFactory");
this.registerType = registerType;
this.registerImplementation = registerImplementation;
}
public override Type CreatesType
{
get { return this.registerImplementation; }
}
public override object GetObject(Type requestedType, TinyIoCContainer container, NamedParameterOverloads parameters, ResolveOptions options)
{
if (parameters.Count != 0)
throw new ArgumentException("Cannot specify parameters for singleton types");
int hashCode = 0;
// if the registered type is an open generic....
if(registerType.IsGenericType && registerType.GetGenericArguments().All(x => x.FullName == null))
{
// then the requested type should have the parameters defined.
hashCode = requestedType.GetGenericArguments().Sum(x => x.GetHashCode());
}else
{
// just a regular old singleton registration with a single stored instance
hashCode = 0;
}
lock (SingletonLock)
{
if (!_Current.ContainsKey(hashCode))
_Current[hashCode] = container.ConstructType(requestedType, this.registerImplementation, Constructor, options);
return _Current[hashCode];
}
}
public override ObjectFactoryBase SingletonVariant
{
get
{
return this;
}
}
public override ObjectFactoryBase GetCustomObjectLifetimeVariant(ITinyIoCObjectLifetimeProvider lifetimeProvider, string errorString)
{
return new CustomObjectLifetimeFactory(this.registerType, this.registerImplementation, lifetimeProvider, errorString);
}
public override ObjectFactoryBase MultiInstanceVariant
{
get
{
return new MultiInstanceFactory(this.registerType, this.registerImplementation);
}
}
public override ObjectFactoryBase GetFactoryForChildContainer(Type type, TinyIoCContainer parent, TinyIoCContainer child)
{
// We make sure that the singleton is constructed before the child container takes the factory.
// Otherwise the results would vary depending on whether or not the parent container had resolved
// the type before the child container does.
GetObject(type, parent, NamedParameterOverloads.Default, ResolveOptions.Default);
return this;
}
public void Dispose()
{
if (_Current == null)
return;
foreach(var value in _Current.Values)
{
if(value is IDisposable)
(value as IDisposable).Dispose();
}
}
}
from tinyioc.
@Worthaboutapig I was added as a contributor within the past year and have been resolving and responding to things as I get time... Before that I was in the same shoes as you... A lot of the current requests need a look over again but last time I did they were out dated and out of sync.
from tinyioc.
Here is a failing unit test.
[TestFixture]
public class ContainerTests
{
[Test]
public void Can_store_open_generics_as_singleton()
{
// arrange
var container = new TinyIoCContainer();
// conventions say this will store as singleton by default
container.Register(typeof(IOpenGeneric<>), typeof(OpenGeneric<>));
// act
var type1 = container.Resolve<IOpenGeneric<Type1>>();
var type2 = container.Resolve<IOpenGeneric<Type2>>();
// assert
type1.ShouldNotBeNull();
type2.ShouldNotBeNull();
Assert.IsInstanceOf<OpenGeneric<Type1>>(type1);
Assert.IsInstanceOf<OpenGeneric<Type1>>(type2);
// arrange
type1.Value = 2;
type2.Value = 2;
// act
type1 = container.Resolve<IOpenGeneric<Type1>>();
type2 = container.Resolve<IOpenGeneric<Type2>>();
// assert
type1.Value.ShouldEqual(2);
type2.Value.ShouldEqual(2);
}
public interface IOpenGeneric<T>
{
int Value { get; set; }
}
public class OpenGeneric<T> : IOpenGeneric<T>
{
public OpenGeneric()
{
Value = 1;
}
public int Value{get;set;}
}
public class Type1
{
}
public class Type2
{
}
}
from tinyioc.
Hmmm.... I actually did pretty much the same thing yesterday because the issue came up on Stack Overflow. I think from a design perspective, it might be better to split this out into a GenericSingletonFactory
. I would also rather assert on sameness for the second resolution attempt; the Value
property seems a bit of a crutch. ;-)
from tinyioc.
Has this been resolved/ looked at? I don't see any pull requests. It's a pretty important feature...
from tinyioc.
@Worthaboutapig I couldn't find any pull requests or changes related to this either. It has apparently been fixed by at least @theonlylawislove and me, but as the project seemed to be all but abandoned, obviously nobody ever bothered with a pull request (at least that was my reason).
from tinyioc.
Its far from.abandoned, its in active use in countless projects and is the core of Nancy.
from tinyioc.
I am aware of its role in Nancy, but it looked rather dead around the time this issue was opened; there were lots of issues (like this one) and pull requests that never even got a reaction. (I even considered forking it, because it was important for my work at the time.)
from tinyioc.
I queried whether it had been fixed, as the current release doesn't resolve open generics correctly for me, so I wasn't convinced that @theonlylawislove had fixed it.
I just wanted clarification that it definitely should work...
from tinyioc.
@Worthaboutapig it should work yes, but it appears that it doesn't and as far as I can remember it's not something I've ever fixed.
from tinyioc.
@TeaDrivenDev : the main reason most PRs aren't brought in is because the next logical step for this, after the major perf work I did a while back, is to make it fully PCL, but that work has never been completed in the PR and I haven't had time yet to do it myself (PCLs aren't really something I've played much with).
from tinyioc.
Thanks. I'll try and take a look at it, though I moved on to the NInject plugin instead, as it worked ;) However, the simplicity of the TinyIoC defaults appeals to me.
from tinyioc.
Any progress on fixing the issue? This is a really annoying bug...
from tinyioc.
Can someone submit a pr
from tinyioc.
Really a annoying bug. No option but to change to another IoC.
:(
from tinyioc.
@rpenha, you could submit a pr for this.
from tinyioc.
Don't mean to be rude, but there's dozens of PRs outstanding already. I submitted a fairly simple one that I thought was pretty useful two years ago... and zilch.
If the existing requests are ignored, then why should people submit new ones?
Again, it's a great project and I don't particularly mean to bash the maintainers, but it's effectively dead- the last commit was in April; there's no concerted effort to keep development going or fix serious bugs.
from tinyioc.
We have this problem in one of our projects. I tried the solution from @pauldotknopf and for us it works.
Any plans to fix it in this repo @niemyjski?
The proposed solution is maybe not perfect, but it works. And it will unblock some developers. Not sure if someone has the time to implement a better fix.
from tinyioc.
If you can submit a pr with tests I’ll merge it
from tinyioc.
Related Issues (20)
- Unnecessary SuppressFinalizes HOT 3
- Platform compatibility HOT 7
- Resolving generic type from parent container fails HOT 3
- Injecting IEnumerable<Type> to constructor - unnamed registrations HOT 1
- System.IO.FileNotFoundException with UWP and TinyIoC 1.3.0 HOT 6
- It would be nice to have a .NET Core test app HOT 1
- NuGet Support & Build System HOT 4
- Resolve Issues with 1.4 alpha nuget packages HOT 10
- AutoRegister registers over 10k types when using in Xamarin.Forms HOT 4
- The type.gettypeconStructors method gets seven constructors in .Net Core HOT 3
- QUESTION: Can I disable property injection? HOT 2
- Registering Xamarin.Essentials.Interface HOT 10
- TinyIoC namespace cannot be found HOT 1
- PublishAsync publishes message twice (.netstandard)
- Optimization of objects allocation during auto-registration of TinyIoC HOT 3
- Is this good choice for large scale ASP.NET projects? HOT 1
- TinyIoCResolutionException after multiple calls of AutoRegister
- Should nullable reference types be supported, or have their code analysis warnings disabled inside the file via pragma's? HOT 4
- [.net-ios] Warning : The file 'TinyIoc.cs' does not specify a 'PublishFolderType' metadata, and a default value could not be calculated. HOT 1
- Registering any class with a copy constructor throws a System.TypeInitializationException HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from tinyioc.