Skip to content

How to upgrade to v4+ #97

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
rikrak opened this issue Mar 13, 2019 · 30 comments
Closed

How to upgrade to v4+ #97

rikrak opened this issue Mar 13, 2019 · 30 comments
Assignees

Comments

@rikrak
Copy link

rikrak commented Mar 13, 2019

Description

I've upgraded my Unity.Abstractions references from v3.3.0 to v4.1.0 (along with other related unity packages) and there appears to be some breaking changes.

At the moment I'm not sure how to go about fixing my code; Is there any upgrade guidance available?
(I've spent the morning googling around, but not found anything so far, but I may be using the wrong search terms :-) )

@ENikS
Copy link
Contributor

ENikS commented Mar 13, 2019 via email

@Ronosho
Copy link

Ronosho commented Mar 13, 2019

I have the same problem.

I'm using new ParameterOverrides for a
public static T Retrieve<T>(params ResolverOverride[] parameterOverride) { return Containter.Resolve<T>(parameterOverride); }
method.
This no longer works with the new version as it's unable to resolve the method.
Any pointers for this?

@ENikS
Copy link
Contributor

ENikS commented Mar 13, 2019 via email

@Ronosho
Copy link

Ronosho commented Mar 13, 2019

After upgrading the code no longer compiles, I have yet found a way to fix my code to build

@ENikS
Copy link
Contributor

ENikS commented Mar 13, 2019

@Ronosho

I would assume it is similar to this one.

There are few samples on how to use Parameter injection.

@rikrak
Copy link
Author

rikrak commented Mar 13, 2019

I'll add my Build issues (and solutions) one at a time on this thread for others to benefit from :-)

Problem:

Build error
The type or namespace name 'IBuilderContext' could not be found

Solution:

IBuilderContext has been replaced with: Unity.Builder.BuilderContext

@rikrak
Copy link
Author

rikrak commented Mar 13, 2019

Problem:

Build Error
'IBuildPlanCreatorPolicy' is obsolete: 'This interface has been replaced with Unity.Policy.ResolveDelegateFactory delegate'

Solution

see this example or this example

@rikrak
Copy link
Author

rikrak commented Mar 13, 2019

Problem:

Build Error in BuilderStrategy derived classes:
'MyCustomStrategy.PreBuildUp(BuilderContext)': no suitable method found to override

Solution:

Adjust the signature of the PreBuildUp method to:
public override void PreBuildUp(ref BuilderContext context)

@rikrak
Copy link
Author

rikrak commented Mar 13, 2019

Problem:

Build Error in BuilderStrategy derived classes:
'MyCustomStrategy.PostBuildUp(BuilderContext)': no suitable method found to override

Solution:

Adjust the signature of the PostBuildUp method to:
public override void PreBuildUp(ref BuilderContext context)

@ENikS
Copy link
Contributor

ENikS commented Mar 13, 2019

@rikrak
For IBuildPlanCreatorPolicy I can suggest this example

@rikrak
Copy link
Author

rikrak commented Mar 14, 2019

Problem:

Build Error in Builder Strategy derived class:
'BuilderContext' does not contain a definition for 'AddResolverOverrides' and no accessible extension method 'AddResolverOverrides' accepting a first argument of type 'BuilderContext' could be found

Solution:

The behaviour can be mimiced by something like:

        public static void AddResolverOverrides(ref BuilderContext ctx, ResolverOverride theOverride)
        {
            var newOverrides = ctx.Overrides;
            newOverrides = newOverrides == null 
                ? new ResolverOverride[]{theOverride} 
                : newOverrides.Concat(new[] {theOverride}).ToArray();

            ctx.Overrides = newOverrides;
        }

Not entirely sure if this is the right way to go about it though...

@rikrak
Copy link
Author

rikrak commented Mar 14, 2019

Problem:

'BuilderContext' does not contain a definition for 'ParentContext' and no accessible extension method 'ParentContext' accepting a first argument of type 'BuilderContext' could be found

I used the ParentContext of IBuilderContext to determine if anything in the build hierarchy was of a certain type. More specifically I was checking to see if a specific decorator class was being applied as part of the build.

Solution:

There is an IntPtr Parent property on the BuilderContext struct. Can this be used to find the parent context?

@rikrak
Copy link
Author

rikrak commented Mar 14, 2019

Problem:

There is a build warning:
'InjectionFactory' is obsolete: 'InjectionFactory has been deprecated and will be removed in next release. Please use IUnityContainer.RegisterFactory(...) method instead.'

Solution:

The InjectionFactory class has been deprecated. Injection factories are now registered directly with the container.
For example:

Old code:
Container.RegisterType<IEncryptionProvider>(new ContainerControlledLifetimeManager(), new InjectionFactory(c => MakeEncryptionProvider(c)));

New code:
Container.RegisterFactory<IEncryptionProvider>(c => MakeEncryptionProvider(c), new ContainerControlledLifetimeManager());

@rikrak
Copy link
Author

rikrak commented Mar 14, 2019

Be Aware:

The public key token of the assembly has changed, so you may need to remove redundant assembly bindings from config files.

For example:
This binding will now be ineefective, and can be removed:

      <dependentAssembly>
        <assemblyIdentity name="Unity.Abstractions" publicKeyToken="6d32ff45e0ccc69f" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.3.0.0" newVersion="3.3.0.0" />
      </dependentAssembly>

Note:

  • the old public key token value is 6d32ff45e0ccc69f
  • the new public key token is 489b6accfaf20ef0

@Ronosho
Copy link

Ronosho commented Mar 15, 2019

Problem

I'm using this code to register my interfaces.
Containter.RegisterType<ICustomerRepository, CustomerRepository>(new ContainerControlledLifetimeManager(), InjectionConstructor);

but after the upgrade im getting the following error when resolving

Exception thrown: 'System.InvalidCastException' in Unity.Abstractions.dll
Unable to cast object of type

@rikrak
Copy link
Author

rikrak commented Mar 15, 2019

@Ronosho Could you provide a bit more detail? The code you've provided doesn't compile for me.
I tried my own example (see below), which works fine for me:

public class Tests
    {
        [TestMethod]
        public void ShouldResolveAlternativeImplementationWhenUsingOverride()
        {
            // arrange
            var target = new UnityContainer();
            target
                .RegisterType<IController, TheController>(new ContainerControlledLifetimeManager(), new InjectionConstructor(new AlternativeMessageProvider()))
                .RegisterType<IMessageProvider, DefaultMessageProvider>()
                ;

            // act
            var actual = target.Resolve<IController>(); 

            // assert
            Assert.AreEqual(actual.GetMessage(), "Goodbye cruel world!");
        }
    }

    public interface IController
    {
        string GetMessage();
    }

    public class TheController : IController
    {
        private readonly IMessageProvider _messageProvider;

        public TheController(IMessageProvider messageProvider)
        {
            _messageProvider = messageProvider;
        }

        public string GetMessage()
        {
            return _messageProvider.CalculateMessage();
        }
    }

    public interface IMessageProvider
    {
        string CalculateMessage();
    }

    class DefaultMessageProvider : IMessageProvider
    {
        public string CalculateMessage()
        {
            return "Hello World";
        }
    }

    class AlternativeMessageProvider : IMessageProvider
    {
        public string CalculateMessage()
        {
            return "Goodbye cruel world!";
        }
    }

@rikrak
Copy link
Author

rikrak commented Mar 15, 2019

Problem:

Build Error in BuilderStrategy derived classes:
'MyCustomStrategy.PostBuildUp(BuilderContext)': no suitable method found to override

Solution:

Adjust the signature of the PostBuildUp method to:
public override void PreBuildUp(ref BuilderContext context)

@Ronosho
Copy link

Ronosho commented Mar 15, 2019

Solution

Ok I managed to find out what I was doing wrong.
I was reussing the same InjectionConstructor for all my registrations.
After replacing them with a new instance for each my problem went away.

@ENikS
Copy link
Contributor

ENikS commented Mar 15, 2019

@Ronosho

Enabling Diagnostic extension should have helped you. It suppose to throw on injectors reuse.

var container = new UnityContainer();
container.EnableDiagnostic();
...

This extension method only works in DEBUG mode.

@ENikS ENikS self-assigned this Mar 15, 2019
@Ronosho
Copy link

Ronosho commented Mar 15, 2019

@ENikS I did not realize we could do that, thanks.
Was the injectors reuse a recent change?

@ENikS
Copy link
Contributor

ENikS commented Mar 15, 2019

It changed in 5.9.0

@ENikS
Copy link
Contributor

ENikS commented Mar 19, 2019

@rikrak

The flow of issues seems to be drying out. Are you closer to finishing your upgrage?

@rikrak
Copy link
Author

rikrak commented Mar 19, 2019 via email

@rikrak
Copy link
Author

rikrak commented Mar 28, 2019

I've upgraded my solution today, and all looks good. This issue can be closed.
Many thanks for your help @ENikS :-)

@rikrak rikrak closed this as completed Mar 28, 2019
@MousekeAcknowledge
Copy link

MousekeAcknowledge commented Aug 23, 2019

I'm currently upgrading all my NuGet packages in our solution, I'm not familiar with Unity at all but upgrading gave some breaking issues, I solved some but this one I cannot seem to figure out.

container.RegisterType<ICommunicationService>(
new InjectionFactory(cont =>
                {
                    string refreshToken = HttpContext.Current.Request.Cookies[AccountClient.RefreshTokenCookieName]?.Value;
                    return new CommunicationService(cont.Resolve<IRequestBuilderService>(),
                                                    cont.Resolve<IConfigService>(),
                                                    LogManager.GetLogger("Log"),
                                                    cont.Resolve<AuthenticationHeaderValue>(),
                                                    refreshToken);
                }),
                new Interceptor<InterfaceInterceptor>(),
                new InterceptionBehavior<LogInterceptor>());

The application tells me this 'InjectionFactory' is obsolete: 'InjectionFactory has been deprecated and will be removed in next release. Please use IUnityContainer.RegisterFactory(...) method instead.', I had several other RegisterType calls but replaced them all with RegisterFactory. But there seem to be no RegisterFactory for InjectionMembers.

public static IUnityContainer RegisterType<T>(this IUnityContainer container, params InjectionMember[] injectionMembers);

Same problem with RegisterSingleTon

ApplicationServiceFactory.Instance.RegisterSingleton<IConfigService>(new InjectionFactory(c => configServiceMock.Object));

I'm currently suppressing it but I would rather fix it.

@ENikS
Copy link
Contributor

ENikS commented Aug 23, 2019 via email

@BishSum
Copy link

BishSum commented Dec 3, 2019

Can any one implemented the below functionality in New Version. I am pretty new to Unity if you can guide how to achieve below behavior. Thanks

Source https://mikaelkoskinen.net/post/unity-passing-constructor-parameters-to-resolve

public class OrderedParametersOverride : ResolverOverride
{
private readonly Queue parameterValues;

public OrderedParametersOverride(IEnumerable<object> parameterValues)
{
    this.parameterValues = new Queue<InjectionParameterValue>();
    foreach (var parameterValue in parameterValues)
    {
        this.parameterValues.Enqueue(InjectionParameterValue.ToParameter(parameterValue));
    }
}

public override IDependencyResolverPolicy GetResolver(IBuilderContext context, Type dependencyType)
{
    if (parameterValues.Count < 1)
        return null;

    var value = this.parameterValues.Dequeue();
    return value.GetResolverPolicy(dependencyType);
}

}

@Farami
Copy link

Farami commented Feb 6, 2020

What happened to DependencyOverrides and PropertyOverrides? They seem to be gone in v4+.

@roblapp
Copy link

roblapp commented Jul 29, 2020

The number of changes in each Unity version is out of control. Many breaking changes with little to no documentation.

@ENikS
Copy link
Contributor

ENikS commented Jul 29, 2020

Writing documentation is not my strongest skill. Would you like to help improving the docs?
Or perhaps you could sponsor hiring a technician writer?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants