unitycontainer / container Goto Github PK
View Code? Open in Web Editor NEWUnity.Container implementation.
License: Apache License 2.0
Unity.Container implementation.
License: Apache License 2.0
Consider following registration:
interface IEmailService : IService
{
}
container.RegisterType<IService, EmailService>();
container.RegisterType<IEmailService, IService>("one");
This fails but it should be allowed situation.
Hello,
We use to create and use a simple custom PerRequestLifetimeManager.
We now want to updgrade to the unity 5.5.0 and I do not really know how to handle the protected override LifetimeManager OnCreateLifetimeManager()
Do you have any sample on creating or upgrading old custom LifeTimeManager to the new version?
Can you please put me on the right track with this:
public class PerRequestLifetimeManager : LifetimeManager
{
private readonly string _key = Guid.NewGuid().ToString();
public override object GetValue()
{
if (HttpContext.Current != null && HttpContext.Current.Items.Contains(_key))
{
return HttpContext.Current.Items[_key];
}
return null;
}
public override void SetValue(object value)
{
if (HttpContext.Current != null)
{
HttpContext.Current.Items[_key] = value;
}
}
public override void RemoveValue()
{
if (HttpContext.Current != null)
{
HttpContext.Current.Items.Remove(_key);
}
}
}
New way?
public class PerRequestLifetimeManager : LifetimeManager
{
public override object GetValue(ILifetimeContainer container = null)
{
throw new NotImplementedException();
}
public override void RemoveValue(ILifetimeContainer container = null)
{
throw new NotImplementedException();
}
public override void SetValue(object newValue, ILifetimeContainer container = null)
{
throw new NotImplementedException();
}
protected override LifetimeManager OnCreateLifetimeManager()
{
throw new NotImplementedException();
}
}
Implementation should use derived class
This shortcut should not be used anymore. Use RegisterType instead. Perhaps convert it to Extension method.
Check if there is a better way for doing this:
private static readonly MethodInfo ResolveDependencyMethod =
typeof(IDependencyResolverPolicy).GetTypeInfo()
.GetDeclaredMethod(nameof(IDependencyResolverPolicy.Resolve));
Current resolve pipeline makes numerous calls to IPolicyList.Get() while resolving type. Number of calls could be reduced to speed up resolution
Eliminate dictionary lookup in scopes if nothing is registered
Resolve
Resolve(...)
{
policy = container.GetOrAdd<IResolverPolicy>(type, name);
return = policy.Resolve(container.context, overrides);
}
Optimizing performance requires new Registration Repository. The goal is to select fastest storage mechanism.
Add container reference (IUnityContainer or perhaps IContainerContext) to each instance. - done
Allow alternative to AddResolverOverrides()
No need for two NewBuildUp
-- BuilderContextExtensions - ?
Fairly certain this is changed behavior from v3. Not sure if this is intended or not.
Here's a gist of the issue. The last two tests fail.
https://gist.github.com/dcomartin/6cc581c36cee7ac0cdd79af6d3d42257
It appears that if you specify T2
in RegisterType
, an injection factory isn't used.
If you then try and overwrite that registration, it won't.
为“C:\projects\unity\Container\src\UnityContainer.cs”查找源。Checksum: SHA1 {5b c9 f1 f7 38 bf d3 da 3b 87 0 72 d2 5d 68 25 36 4d cf b5}
文件“C:\projects\unity\Container\src\UnityContainer.cs”不存在。
正在脚本文档中查找“C:\projects\unity\Container\src\UnityContainer.cs”...
正在“编辑并继续”目录“D:\enc_temp_folder\”中查看...
在“编辑并继续”目录中找不到具有匹配校验和的文件。
正在项目中查找“C:\projects\unity\Container\src\UnityContainer.cs”。
在项目中未找到该文件。
活动解决方案的调试源文件设置指明调试器不会要求用户查找文件: C:\projects\unity\Container\src\UnityContainer.cs。
调试器未能找到源文件“C:\projects\unity\Container\src\UnityContainer.cs”。
There are cases when there is a BuildPlanStrategies list per registered strategy. Extension should retrieve appropriate list from relevant strategy.
Perhaps create Extension method which would allow retrieving defaults
Subsequent registrations affecting previously registered mapped types:
[TestMethod]
public void ConflictTypeMapping()
{
IUnityContainer container = new UnityContainer();
container.RegisterType<ILogger, MockLogger>(new ContainerControlledLifetimeManager());
ILogger logger = container.Resolve<ILogger>();
Assert.IsNotNull(logger);
Assert.AreSame(container.Resolve<ILogger>(), logger);
container.RegisterType<MockLogger>(new TransientLifetimeManager());
Assert.AreSame(container.Resolve<ILogger>(), logger);
}
The last assertion is failing.
DynamicMethodConstructorStrategy.cs
DynamicMethodCallStrategy.cs
DynamicMethodPropertySetterStrategy.cs
HierarchicalLifetimeManager.cs
InjectionParameter.cs
LazyDynamicMethodBuildPlanCreatorPolicy.cs
LifetimeStrategy.cs
ResolvedArrayParameter.cs
BuildKeyMappingStrategy.cs
DefaultUnityConstructorSelectorPolicy.cs
I just tried to update from V4.x to v5.1.2 and noticed that the UnityContainer.TearDown method along with the Pre- and PostTearDown code in the UnityContainerExtension is missing.
I use these for cleaning up container created instances and their dependencies with a custom object tracker.
Are you planing to put such a feature in the container itself (like other containers did for a long time)? Will the code come back?
Child containers have registration dictionary even though it might not have any registrations in it. Removing these will speed up resolution and improve look up times.
Resolve how ContainerRegistration uses MappedToType vs RegisteredType
In Unity 6 it is no longer possible to register Types with multiple calls to RegisterType. It was possible to configure registration with a config file or call to RegisterType and later add Interceptors of behaviors.
This no longer works. Each subsequent call to RegisterType completely overwrites pervious registration.
It looks like getting Registrations is quite expensive (2 - 3 iterations at least):
foreach (Type t in registeredNames.RegisteredTypes) - 1
typeRegistrations[t].Concat(registeredNames.GetKeys(t))) - 2
.Distinct().ToList() - 3
This causes a conflict when targeting .net standard 2.0
This lifetime manager should be globally unique singleton and should be the same no matter where in hierarchy it is created or retrieved.
public void Set(Type policyInterface,
IBuilderPolicy policy,
object buildKey)
{
lock (lockObject)
{
Dictionary<PolicyKey, IBuilderPolicy> newPolicies = this.ClonePolicies();
newPolicies[new PolicyKey(policyInterface, buildKey)] = policy;
this.policies = newPolicies;
}
}
It keeps all the old queries valid even when registration has changed.
Need some research if there are better ways.
While creating types builder call constructor and after it is initialized it setts properties and calls dependency methods.
Instead it should generate property initializes and invoke constructor and initialize properties in one call:
... new Constructor(args...) { Prop = xx, OtherProp = yy, ...};
this worked fine in 5.2.0 (as well as previous versions) and not anymore in 5.2.1.
class Program
{
static void Main(string[] args)
{
WorksOnUnityContainer520(new UnityContainer());
Console.ReadLine();
}
static void WorksOnUnityContainer520(IUnityContainer container)
{
container.RegisterType<ITestService, TestService>(new InjectionFactory(c => new TestService(new ModelA())));
var testService = container.Resolve<ITestService>();
}
#region Model
public interface ITestService
{
}
public interface IModelA
{
}
internal sealed class TestService : ITestService
{
private readonly IModelA _a;
public TestService(IModelA a)
{
_a = a;
}
}
internal sealed class ModelA : IModelA
{
}
#endregion
}
I switched to using InjectionConstructor which still works as expected.
Hi there. I'm building an app using Prism 7 and Unity 5 and I'm trying to make a module with optional dependency in it's constructor as follows:
[Module]
[ModuleDependency("OptionalDependencyModule")]
public class Module : IModule
{
public Module([OptionalDependency] IOptionalDependencyModule module)
{
...
}
}
But if Unity doesn't find .dll with "OptionalDependencyModule" (I'm using DirectoryModuleCatalog), it still throws an exception instead of just passing null (this behaviour is what I'm looking for).
If I remove 2nd string, it passes null
even though requested module is available as usual.
So how do I make optional dependency? Thanks.
LifetimeContainer should be HashSet based. In case item is added twice it should not Dispose() it multiple times.
@davidshen84 wrote:
The following code will not work:
_container = new UnityContainer()
.AddNewExtension<Interception>()
.RegisterType<ObjectCache, MemoryCache>(
new InjectionConstructor("some_cache")));
Because MemoryCache
type require two parameters in the constructor, a string which is required, and a NameValueCollection which is defaulted to null.
In my case, I have to provide a non-null instance of the type NameValueCollection. But it would be more convenient if we do not need to provide parameters that already have a default value.
Verify if this could be replaced with faster mechanism
All the samples I've found are old and require instantiating the container to resolve dependencies.
Is that how this container is designed to work, always calling UnityContainer.Resolve()?
Where can I find good samples for MVC5 and console apps?
DynamicMethodConstructorStrategy:
private static readonly MethodInfo ThrowForNullExistingObjectMethod =
typeof(DynamicMethodConstructorStrategy).GetTypeInfo().DeclaredMethods
.First(m => Equals(m.Name, nameof(DynamicMethodConstructorStrategy.ThrowForNullExistingObject)));
private static readonly MethodInfo ThrowForNullExistingObjectWithInvalidConstructorMethod =
typeof(DynamicMethodConstructorStrategy).GetTypeInfo().DeclaredMethods
.First(m => Equals(m.Name, nameof(DynamicMethodConstructorStrategy.ThrowForNullExistingObjectWithInvalidConstructor)));
private static readonly MethodInfo ThrowForReferenceItselfConstructorMethod =
typeof(DynamicMethodConstructorStrategy).GetTypeInfo().DeclaredMethods
.First(m => Equals(m.Name, nameof(DynamicMethodConstructorStrategy.ThrowForReferenceItselfConstructor)));
private static readonly MethodInfo ThrowForAttemptingToConstructInterfaceMethod =
typeof(DynamicMethodConstructorStrategy).GetTypeInfo().DeclaredMethods
.First(m => Equals(m.Name, nameof(DynamicMethodConstructorStrategy.ThrowForAttemptingToConstructInterface)));
private static readonly MethodInfo ThrowForAttemptingToConstructAbstractClassMethod =
typeof(DynamicMethodConstructorStrategy).GetTypeInfo().DeclaredMethods
.First(m => Equals(m.Name, nameof(DynamicMethodConstructorStrategy.ThrowForAttemptingToConstructAbstractClass)));
private static readonly MethodInfo ThrowForAttemptingToConstructDelegateMethod =
typeof(DynamicMethodConstructorStrategy).GetTypeInfo().DeclaredMethods
.First(m => Equals(m.Name, nameof(DynamicMethodConstructorStrategy.ThrowForAttemptingToConstructDelegate)));
private static readonly MethodInfo SetCurrentOperationToResolvingParameterMethod =
typeof(DynamicMethodConstructorStrategy).GetTypeInfo().DeclaredMethods
.First(m => Equals(m.Name, nameof(DynamicMethodConstructorStrategy.SetCurrentOperationToResolvingParameter)));
private static readonly MethodInfo SetCurrentOperationToInvokingConstructorMethod =
typeof(DynamicMethodConstructorStrategy).GetTypeInfo().DeclaredMethods
.First(m => Equals(m.Name, nameof(DynamicMethodConstructorStrategy.SetCurrentOperationToInvokingConstructor)));
private static readonly MethodInfo SetPerBuildSingletonMethod =
typeof(DynamicMethodConstructorStrategy).GetTypeInfo().DeclaredMethods
.First(m => Equals(m.Name, nameof(DynamicMethodConstructorStrategy.SetPerBuildSingleton)));
I'm having trouble finding out how to perform the container.RegisterTypes call after upgrading.
Is this still possible and if so how?
IUnityContainer container = new UnityContainer();
var ss1 = container.Resolve<object>();
var ss2 = container.Resolve<object>(name); <-- This should fail
Policies to override registrations are added even though no existing registrations exist
Why do you take time to reverse the itemsCopy list?
90 var itemsCopy = new List<object>(_items);
91 itemsCopy.Reverse();
92
93 foreach (object o in itemsCopy)
94 {
95 if (o is IDisposable d)
96 {
97 d.Dispose();
98 }
99 }
100
101 _items.Clear();
Currently Container processes registrations and adds required policies for the strategies. To add flexibility and provide better separation of concerns strategies should participate in registration process and add required policies.
This will allow strategies like Type Interceptor to analyze registered type early on and avoid doing it for each transient resolution of the type.
To enable this feature new interface is created:
public interface IRegisterTypeStrategy
{
/// <summary>
/// Register a type mapping with the container, where the created instances will use
/// the given <see cref="LifetimeManager"/>.
/// </summary>
/// <param name="policies"><see cref="IPolicyList"/> holding the registration.</param>
/// <param name="typeFrom"><see cref="Type"/> that will be requested.</param>
/// <param name="typeTo"><see cref="Type"/> that will actually be returned.</param>
/// <param name="name">Name to use for registration, null if a default registration.</param>
/// <param name="lifetimeManager">The <see cref="LifetimeManager"/> that controls the lifetime
/// of the returned instance.</param>
/// <param name="injectionMembers">Injection configuration objects. Can be null.</param>
void RegisterType(IContainerContext context,
Type typeFrom, Type typeTo, string name,
LifetimeManager lifetimeManager,
params InjectionMember[] injectionMembers);
}
Each strategy that wishes to participate in the registration process implements this interface.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.