Skip to content
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

.NET Core transition: Inject service interfaces wherever possible #7369

Closed
bergmania opened this issue Dec 19, 2019 · 20 comments
Closed

.NET Core transition: Inject service interfaces wherever possible #7369

bergmania opened this issue Dec 19, 2019 · 20 comments

Comments

@bergmania
Copy link
Member

This task is up for grabs, for contributing to the .NET Core transition project

On the development branch of the .net core transition project netcore/dev, we have used Current.Services.* a lot.

When this is used, we cannot move the class into Umbraco.Abstractions or Umbraco.Infrastructure.

This task is about eliminating the usage of Current.Services.* in general, by replacing it with a constructor injection of the interface of the given service that is in use. E.g. Current.Services.LocalizationService has to be replaced with injection of ILocalizationService.

Expected Procedure:

  • Find an instance class that uses Current.Services.*.
  • Add the interface of the service to the constructor.
  • Save the variable in a private readonly field.
  • Replace the usages of Current.Services.* with the field.
  • Make sure the project builds
    • Often you will need to inject this into classes that uses this specific class
  • Ensure unit tests all pass
  • Repeat the process

If any questions, feel free to ask :)

Feel free to resolve this task in multiple smaller PRs, Due to the fact long running feature branch most likely have merge conflict with netcore/dev

@hishamco
Copy link

I'm an Umbraco fan from version 3 or 4, so I decide to pick this one as my first contribution to the great ecosystem

@hishamco
Copy link

While this is a huge change I will break this task into many PRs per service

@Shazwazza where should I register the services, I don't see IStartup implementation or the web app is not created yet?

@hishamco
Copy link

hishamco commented Dec 25, 2019

@Shazwazza
Copy link
Contributor

Wonderful initiative @hishamco !

I'll create some review tasks to have a look at your PRs hopefully within the next week.

I did notice that in some of your PRs that you are removing services from the ServiceContext but we don't want to do that. The ServiceContext shouldn't be changed. The main task for all of this is to remove the usages of the Current singleton.

Thanks!

@Shazwazza
Copy link
Contributor

@hishamco Ideally we want to have minimal amount of changes where necessary. While I appreciate the huge effort to remove the usages of ServiceContext it is not necessary and actually makes merge cases and the transition to the next version a little more difficult.

Ideally we just want to have the Current singleton usages removed but the existing ServiceContext usages should remain in most cases

@hishamco
Copy link

Ok, I will revert my changes in the ServiceContext

@bergmania
Copy link
Member Author

bergmania commented Jan 8, 2020

Hi @hishamco..

I also looked into some of the PRs, but none of them actually removes any usages of Current.Services.

Here is an example of how to fix a single file (Diff version):
Before:

using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Services;
using Umbraco.Core.Services.Implement;
using Current = Umbraco.Web.Composing.Current;

namespace Umbraco.Web.Compose
{
    public sealed class PublicAccessComponent : IComponent
    {
        public void Initialize()
        {
            MemberGroupService.Saved += MemberGroupService_Saved;
        }

        public void Terminate()
        { }

        static void MemberGroupService_Saved(IMemberGroupService sender, Core.Events.SaveEventArgs<Core.Models.IMemberGroup> e)
        {
            foreach (var grp in e.SavedEntities)
            {
                //check if the name has changed
                if (grp.AdditionalData.ContainsKey("previousName")
                    && grp.AdditionalData["previousName"] != null
                    && grp.AdditionalData["previousName"].ToString().IsNullOrWhiteSpace() == false
                    && grp.AdditionalData["previousName"].ToString() != grp.Name)
                {
                    Current.Services.PublicAccessService.RenameMemberGroupRoleRules(grp.AdditionalData["previousName"].ToString(), grp.Name);
                }
            }
        }
    }
}

After

using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Services;
using Umbraco.Core.Services.Implement;

namespace Umbraco.Web.Compose
{
    public sealed class PublicAccessComponent : IComponent
    {
        private readonly IPublicAccessService _publicAccessService;

        public PublicAccessComponent(IPublicAccessService publicAccessService)
        {
            _publicAccessService = publicAccessService;
        }

        public void Initialize()
        {
            MemberGroupService.Saved += (sender, args) => MemberGroupService_Saved(_publicAccessService, sender, args);
        }

        public void Terminate()
        { }

        static void MemberGroupService_Saved(IPublicAccessService publicAccessService, IMemberGroupService sender, Core.Events.SaveEventArgs<Core.Models.IMemberGroup> e)
        {
            foreach (var grp in e.SavedEntities)
            {
                //check if the name has changed
                if (grp.AdditionalData.ContainsKey("previousName")
                    && grp.AdditionalData["previousName"] != null
                    && grp.AdditionalData["previousName"].ToString().IsNullOrWhiteSpace() == false
                    && grp.AdditionalData["previousName"].ToString() != grp.Name)
                {
                    publicAccessService.RenameMemberGroupRoleRules(grp.AdditionalData["previousName"].ToString(), grp.Name);
                }
            }
        }
    }
}

As you can see, before Current.Services.PublicAccessService was used.
We introduce a constructor that takes a IPublicAccessService and saves that into a field _publicAccessService . We then uses _publicAccessService instead of the Current.Services.PublicAccessService

@hishamco
Copy link

hishamco commented Jan 8, 2020

@bergmania I knew how to fix it ;)

I also looked into some of the PRs, but none of them actually removes any usages of Current.Services.

Could you please refer me to one file that didn't have the change? perhaps it's missed accidentally

@bergmania
Copy link
Member Author

@hishamco, if I look at the changes here: https://github.com/umbraco/Umbraco-CMS/pull/7390/files
No changes involve removing Current.Services.

@hishamco
Copy link

hishamco commented Jan 8, 2020

Let me check ...

@bergmania
Copy link
Member Author

Hi @hishamco..

Based on the changes on the PRs, I still in doubt that you understand the meaning of this issue.

Basically it is just these 110 occurrences that should be eliminated, or at least as many of them as possible:

Search target
    Umbraco.Web.Composing.Current.Services:ServiceContext
Found usages  (110 usages found)
    Read access  (110 usages found)
        <Tests>  (50 usages found)
            <Umbraco.Tests>  (50 usages found)
                Cache  (7 usages found)
                    PublishedCache  (5 usages found)
                        PublishedContentCacheTests.cs  (3 usages found)
                            (73: 66)  new PublishedMemberCache(null, appCache, Current.Services.MemberService, ContentTypesCache, Current.Services.UserService, VariationContextAccessor),
                            (73: 117)  new PublishedMemberCache(null, appCache, Current.Services.MemberService, ContentTypesCache, Current.Services.UserService, VariationContextAccessor),
                            (81: 74)  new WebSecurity(_httpContextFactory.HttpContext, Current.Services.UserService, globalSettings),
                        PublishedMediaCacheTests.cs  (2 usages found)
                            (99: 128)  …l, null, null, null, HostingEnvironment), Current.Services.MediaService, Current.Services.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance<IEntityXmlSerializer>(), Factor…
                            (99: 159)  …ironment), Current.Services.MediaService, Current.Services.UserService, new DictionaryAppCache(), ContentTypesCache, Factory.GetInstance<IEntityXmlSerializer>(), Factory.GetInstance<IUmbracoContextAc…
                    DistributedCacheBinderTests.cs  (2 usages found)
                        (42: 42)  var serviceContext = Current.Services;
                        (150: 101)  new EventDefinition<IContentTypeService, SaveEventArgs<IContentType>>(null, Current.Services.ContentTypeService, new SaveEventArgs<IContentType>(Enumerable.Empty<IContentType>()), "Saved"),
                Issues  (1 usage found)
                    U9560.cs  (1 usage found)
                        (25: 21)  Current.Services.ContentTypeService.Save(contentType);
                LegacyXmlPublishedCache  (1 usage found)
                    PublishedMediaCache.cs  (1 usage found)
                        (562: 33)  var media = Current.Services.MediaService.GetById(parentId);
                Models  (3 usages found)
                    Mapping  (3 usages found)
                        ContentWebModelMappingTests.cs  (3 usages found)
                            (255: 77)  Assert.IsTrue(invariantContent.Tabs.Any(x => x.Label == Current.Services.TextService.Localize("general/properties")));
                            (256: 84)  …variantContent.Tabs.Where(x => x.Label == Current.Services.TextService.Localize("general/properties")).SelectMany(x => x.Properties.Where(p => p.Alias.StartsWith("_umb_") == false…
                            (351: 37)  Assert.AreEqual(Current.Services.DataTypeService.GetDataType(p.PropertyType.DataTypeId), pDto.DataType);
                PublishedContent  (5 usages found)
                    PublishedContentDataTableTests.cs  (3 usages found)
                        (81: 50)  var dt = doc.ChildrenAsTable(Current.Services);
                        (104: 50)  var dt = doc.ChildrenAsTable(Current.Services, "Child");
                        (120: 50)  var dt = doc.ChildrenAsTable(Current.Services);
                    PublishedContentExtensionTests.cs  (1 usage found)
                        (76: 50)  var contentTypeService = Current.Services.ContentTypeService;
                    PublishedContentSnapshotTestBase.cs  (1 usage found)
                        (74: 54)  new WebSecurity(httpContext, Current.Services.UserService, globalSettings),
                Routing  (2 usages found)
                    ContentFinderByUrlAndTemplateTests.cs  (1 usage found)
                        (22: 21)  Current.Services.FileService.SaveTemplate(template);
                    RenderRouteHandlerTests.cs  (1 usage found)
                        (93: 21)  Current.Services.FileService.SaveTemplate(template);
                Scoping  (13 usages found)
                    ScopedNuCacheTests.cs  (4 usages found)
                        (123: 54)  new WebSecurity(httpContext, Current.Services.UserService, globalSettings),
                        (149: 21)  Current.Services.ContentTypeService.Save(contentType);
                        (167: 25)  Current.Services.ContentService.SaveAndPublish(item);
                        (181: 25)  Current.Services.ContentService.SaveAndPublish(item);
                    ScopedRepositoryTests.cs  (3 usages found)
                        (63: 35)  var service = Current.Services.UserService;
                        (140: 35)  var service = Current.Services.LocalizationService;
                        (232: 35)  var service = Current.Services.LocalizationService;
                    ScopedXmlTests.cs  (6 usages found)
                        (92: 21)  Current.Services.ContentTypeService.Save(contentType);
                        (129: 25)  Current.Services.ContentService.SaveAndPublish(item); // should create an xml clone
                        (131: 25)  Current.Services.ContentService.SaveAndPublish(item); // should re-use the xml clone
                        (206: 21)  Current.Services.ContentTypeService.Save(contentType);
                        (228: 25)  Current.Services.ContentService.SaveAndPublish(item);
                        (233: 29)  Current.Services.ContentService.SaveAndPublish(temp);
                Security  (2 usages found)
                    BackOfficeCookieManagerTests.cs  (2 usages found)
                        (36: 69)  new WebSecurity(Mock.Of<HttpContextBase>(), Current.Services.UserService, globalSettings),
                        (56: 69)  new WebSecurity(Mock.Of<HttpContextBase>(), Current.Services.UserService, globalSettings),
                TestHelpers  (1 usage found)
                    TestWithDatabaseBase.cs  (1 usage found)
                        (57: 60)  protected ServiceContext ServiceContext => Current.Services;
                Web  (15 usages found)
                    Controllers  (11 usages found)
                        AuthenticationControllerTests.cs  (1 usage found)
                            (64: 56)  var userServiceMock = Mock.Get(Current.Services.UserService);
                        ContentControllerTests.cs  (7 usages found)
                            (161: 34)  Mock.Get(Current.Services.ContentTypeService)
                            (164: 34)  Mock.Get(Current.Services.ContentTypeService)
                            (255: 59)  var contentServiceMock = Mock.Get(Current.Services.ContentService);
                            (334: 59)  var contentServiceMock = Mock.Get(Current.Services.ContentService);
                            (380: 59)  var contentServiceMock = Mock.Get(Current.Services.ContentService);
                            (420: 59)  var contentServiceMock = Mock.Get(Current.Services.ContentService);
                            (466: 59)  var contentServiceMock = Mock.Get(Current.Services.ContentService);
                        UsersControllerTests.cs  (3 usages found)
                            (67: 56)  var userServiceMock = Mock.Get(Current.Services.UserService);
                            (176: 56)  var userServiceMock = Mock.Get(Current.Services.UserService);
                            (253: 56)  var userServiceMock = Mock.Get(Current.Services.UserService);
                    Mvc  (1 usage found)
                        UmbracoViewPageTests.cs  (1 usage found)
                            (443: 47)  new WebSecurity(http, Current.Services.UserService, globalSettings),
                    WebExtensionMethodTests.cs  (3 usages found)
                        (32: 69)  new WebSecurity(Mock.Of<HttpContextBase>(), Current.Services.UserService, TestObjects.GetGlobalSettings()),
                        (52: 69)  new WebSecurity(Mock.Of<HttpContextBase>(), Current.Services.UserService, TestObjects.GetGlobalSettings()),
                        (82: 69)  new WebSecurity(Mock.Of<HttpContextBase>(), Current.Services.UserService, TestObjects.GetGlobalSettings()),
        <Umbraco.Web>  (60 usages found)
            Compose  (1 usage found)
                PublicAccessComponent.cs  (1 usage found)
                    (29: 29)  Current.Services.PublicAccessService.RenameMemberGroupRoleRules(grp.AdditionalData["previousName"].ToString(), grp.Name);
            Editors  (20 usages found)
                Binders  (3 usages found)
                    ContentItemBinder.cs  (1 usage found)
                        (22: 67)  public ContentItemBinder() : this(Current.Logger, Current.Services, Current.UmbracoContextAccessor)
                    MediaItemBinder.cs  (1 usage found)
                        (19: 49)  public MediaItemBinder() : this(Current.Services)
                    MemberBinder.cs  (1 usage found)
                        (24: 46)  public MemberBinder() : this(Current.Services, Current.ShortStringHelper)
                Filters  (15 usages found)
                    ContentSaveValidationAttribute.cs  (4 usages found)
                        (33: 111)  …t.Logger, Current.UmbracoContextAccessor, Current.Services.TextService, Current.Services.ContentService, Current.Services.UserService, Current.Services.EntityService)
                        (33: 141)  …xtAccessor, Current.Services.TextService, Current.Services.ContentService, Current.Services.UserService, Current.Services.EntityService)
                        (33: 174)  …Service, Current.Services.ContentService, Current.Services.UserService, Current.Services.EntityService)
                        (33: 204)  …entService, Current.Services.UserService, Current.Services.EntityService)
                    MediaItemSaveValidationAttribute.cs  (3 usages found)
                        (27: 114)  public MediaItemSaveValidationAttribute() : this(Current.Logger, Current.UmbracoContextAccessor, Current.Services.TextService, Current.Services.MediaService, Current.Services.EntityService)
                        (27: 144)  public MediaItemSaveValidationAttribute() : this(Current.Logger, Current.UmbracoContextAccessor, Current.Services.TextService, Current.Services.MediaService, Current.Services.EntityService)
                        (27: 175)  public MediaItemSaveValidationAttribute() : this(Current.Logger, Current.UmbracoContextAccessor, Current.Services.TextService, Current.Services.MediaService, Current.Services.EntityService)
                    MemberSaveValidationAttribute.cs  (3 usages found)
                        (25: 76)  : this(Current.Logger, Current.UmbracoContextAccessor, Current.Services.TextService, Current.Services.MemberTypeService, Current.Services.MemberService, Current.ShortStringHelper)
                        (25: 106)  : this(Current.Logger, Current.UmbracoContextAccessor, Current.Services.TextService, Current.Services.MemberTypeService, Current.Services.MemberService, Current.ShortStringHelper)
                        (25: 142)  : this(Current.Logger, Current.UmbracoContextAccessor, Current.Services.TextService, Current.Services.MemberTypeService, Current.Services.MemberService, Current.ShortStringHelper)
                    UserGroupAuthorizationAttribute.cs  (4 usages found)
                        (54: 25)  new UserGroupEditorAuthorizationHelper( ↵ Current.Services.UserService, ↵ Current.Services.ContentService, ↵ Current.Services.MediaService, ↵ Current.Services.EntityService)
                        (55: 25)  new UserGroupEditorAuthorizationHelper( ↵ Current.Services.UserService, ↵ Current.Services.ContentService, ↵ Current.Services.MediaService, ↵ Current.Services.EntityService)
                        (56: 25)  new UserGroupEditorAuthorizationHelper( ↵ Current.Services.UserService, ↵ Current.Services.ContentService, ↵ Current.Services.MediaService, ↵ Current.Services.EntityService)
                        (57: 25)  new UserGroupEditorAuthorizationHelper( ↵ Current.Services.UserService, ↵ Current.Services.ContentService, ↵ Current.Services.MediaService, ↵ Current.Services.EntityService);
                    UserGroupValidateAttribute.cs  (1 usage found)
                        (32: 69)  private IUserService UserService => _userService ?? Current.Services.UserService; // TODO: inject
                MediaTypeController.cs  (2 usages found)
                    (272: 34)  var entity = Current.Services.EntityService.Get(contentId);
                    (291: 38)  var entity = Current.Services.EntityService.Get(guidUdi.Guid);
            Macros  (1 usage found)
                PublishedContentHashtableConverter.cs  (1 usage found)
                    (210: 43)  var contentType = Current.Services.ContentTypeBaseServices.GetContentTypeOf(_inner);
            Models  (1 usage found)
                Mapping  (1 usage found)
                    TabsAndPropertiesMapper.cs  (1 usage found)
                        (129: 39)  var contentType = Current.Services.ContentTypeBaseServices.GetContentTypeOf(source);
            Mvc  (1 usage found)
                AdminTokenAuthorizeAttribute.cs  (1 usage found)
                    (24: 69)  private IUserService UserService => _userService ?? Current.Services.UserService;
            PublishedCache  (1 usage found)
                NuCache  (1 usage found)
                    PublishedContent.cs  (1 usage found)
                        (62: 39)  var userService = Current.Services?.UserService;
            Security  (5 usages found)
                Providers  (3 usages found)
                    MembersMembershipProvider.cs  (2 usages found)
                        (23: 28)  : this(Current.Services.MemberService, Current.Services.MemberTypeService, Current.UmbracoVersion, Current.HostingEnvironment, Current.IpResolver)
                        (23: 60)  : this(Current.Services.MemberService, Current.Services.MemberTypeService, Current.UmbracoVersion, Current.HostingEnvironment, Current.IpResolver)
                    MembersRoleProvider.cs  (1 usage found)
                        (23: 28)  : this(Current.Services.MemberService)
                AuthenticationExtensions.cs  (1 usage found)
                    (250: 33)  Current.Services.UserService.ClearLoginSession(guidSession);
                MembershipHelper.cs  (1 usage found)
                    (314: 41)  var entityService = Current.Services.EntityService;
            WebApi  (24 usages found)
                Filters  (24 usages found)
                    AdminUsersAuthorizeAttribute.cs  (5 usages found)
                        (52: 33)  var users = Current.Services.UserService.GetUsersById(userIds);
                        (53: 72)  var authHelper = new UserEditorAuthorizationHelper(Current.Services.ContentService, Current.Services.MediaService, Current.Services.UserService, Current.Services.EntityService);
                        (53: 105)  var authHelper = new UserEditorAuthorizationHelper(Current.Services.ContentService, Current.Services.MediaService, Current.Services.UserService, Current.Services.EntityService);
                        (53: 136)  var authHelper = new UserEditorAuthorizationHelper(Current.Services.ContentService, Current.Services.MediaService, Current.Services.UserService, Current.Services.EntityService);
                        (53: 166)  var authHelper = new UserEditorAuthorizationHelper(Current.Services.ContentService, Current.Services.MediaService, Current.Services.UserService, Current.Services.EntityService);
                    CheckIfUserTicketDataIsStaleAttribute.cs  (4 usages found)
                        (73: 32)  var user = Current.Services.UserService.GetUserById(userId.Result);
                        (82: 63)  var culture = user.GetUserCulture(Current.Services.TextService, Current.Configs.Global());
                        (89: 85)  var startContentIds = user.CalculateContentStartNodeIds(Current.Services.EntityService);
                        (94: 81)  var startMediaIds = user.CalculateMediaStartNodeIds(Current.Services.EntityService);
                    EnsureUserPermissionForContentAttribute.cs  (5 usages found)
                        (92: 42)  nodeId = Current.Services.EntityService.GetId(udi).Result;
                        (98: 42)  nodeId = Current.Services.EntityService.GetId(key, UmbracoObjectTypes.Document).Result;
                        (120: 25)  …nt.UmbracoContext.Security.CurrentUser, ↵ Current.Services.UserService, ↵ Current.Services.ContentService, ↵ Current.Services.EntityService, ↵ out var contentItem, ↵ _permissionToCheck.HasValue ? new…
                        (121: 25)  …ntUser, ↵ Current.Services.UserService, ↵ Current.Services.ContentService, ↵ Current.Services.EntityService, ↵ out var contentItem, ↵ _permissionToCheck.HasValue ? new[] { _permissionToCheck.Value } …
                        (122: 25)  …ice, ↵ Current.Services.ContentService, ↵ Current.Services.EntityService, ↵ out var contentItem, ↵ _permissionToCheck.HasValue ? new[] { _permissionToCheck.Value } : null)
                    EnsureUserPermissionForMediaAttribute.cs  (3 usages found)
                        (76: 38)  var found =  Current.Services.EntityService.GetId(guidId, UmbracoObjectTypes.Media);
                        (125: 25)  MediaController.CheckPermissions( ↵ actionContext.Request.Properties, ↵ Current.UmbracoContext.Security.CurrentUser, ↵ Current.Services.MediaService, ↵ Current.Services.EntityService, ↵ nodeId)
                        (126: 25)  MediaController.CheckPermissions( ↵ actionContext.Request.Properties, ↵ Current.UmbracoContext.Security.CurrentUser, ↵ Current.Services.MediaService, ↵ Current.Services.EntityService, ↵ nodeId)
                    FilterAllowedOutgoingContentAttribute.cs  (6 usages found)
                        (27: 42)  : this(outgoingType, Current.Services.UserService, Current.Services.EntityService)
                        (27: 72)  : this(outgoingType, Current.Services.UserService, Current.Services.EntityService)
                        (33: 42)  : this(outgoingType, Current.Services.UserService, Current.Services.EntityService)
                        (33: 72)  : this(outgoingType, Current.Services.UserService, Current.Services.EntityService)
                        (39: 56)  : this(outgoingType, propertyName, Current.Services.UserService, Current.Services.EntityService)
                        (39: 86)  : this(outgoingType, propertyName, Current.Services.UserService, Current.Services.EntityService)
                    FilterAllowedOutgoingMediaAttribute.cs  (1 usage found)
                        (43: 60)  return user.CalculateMediaStartNodeIds(Current.Services.EntityService);
            PublishedContentExtensions.cs  (3 usages found)
                (61: 36)  var template = Current.Services.FileService.GetTemplate(content.TemplateId.Value);
                (73: 55)  var publishedContentContentType = Current.Services.ContentTypeService.Get(content.ContentType.Id);
                (82: 36)  var template = Current.Services.FileService.GetTemplate(templateAlias);
            UmbracoDefaultOwinStartup.cs  (1 usage found)
                (34: 54)  protected ServiceContext Services => Current.Services;
            UmbracoHttpHandler.cs  (1 usage found)
                (17: 83)  : this(Current.UmbracoContextAccessor, Current.UmbracoHelper, Current.Services, Current.ProfilingLogger)
            UmbracoWebService.cs  (1 usage found)
                (35: 104)  : this(Current.ProfilingLogger, Current.UmbracoContextAccessor, Current.UmbracoHelper, Current.Services, Current.Configs.Global())

@kashfshah
Copy link

kashfshah commented Jan 23, 2020

Hi all. The WebApi Filter Attributes are probably going to take some extra attention, as well as any other usages of Current.Services by Attributes.

@benjaminc
Copy link
Contributor

benjaminc commented Jan 23, 2020

The attributes should probably be left until we are on the .NET Core, and can use of the TypeFilterAttribute or ServiceFilterAttribute to inject instances into attribute and filter constructors.

I'll try to do some of there. One question though. There are a number of ones which use Current.Services in a default constructor to call a non-default constructor. Do you want these default constructors removed to remove the Current.Services dependency, or should we leave these alone for now?

@benjaminc
Copy link
Contributor

In then end, I only fixed 6 of the 110 references to Current.Services. The rest break out as follows:

50 - Unit tests (these could likely be done, but not tonight)
40 - Attribute classes (best done with .NET Core and the TypeFilterAttribute)
9 - Default constructors calling DI constructors (see question above)
4 - Extension classes (would need to refactor or add arguments)
1 - PublishedContent with the explicit comment "we don't want each published content to hold a reference to the service"

@bergmania
Copy link
Member Author

bergmania commented Jan 23, 2020

Hi @benjaminc

Good work.. I agree, most of them should just be left for now, but the unit tests could be nice to resolve before we close the issue..

@stevetemple
Copy link
Contributor

1 - PublishedContent with the explicit comment "we don't want each published content to hold a reference to the service"

Is solved by the final version of PR #7542

@bergmania
Copy link
Member Author

Fixed the unit tests here: #7644

I think we can close the issue when this is merged.

@elit0451
Copy link
Member

Merged #7644! As @bergmania suggested, will close the issue

@nul800sebastiaan
Copy link
Member

Good to see this one is done now! Just to get back to @hishamco - thanks again for all your work! ⭐
It's a shame it's not exactly what we wanted to get out of this but hopefully you've learned something new! Make sure to dig into the linked PRs above for some more insight on how this was eventually resolved.
I'll close your open PRs since the required work is now done. ✔

We'll do our best for future tasks to describe what the intention is in a little more detail since we wouldn't want people to spend a lot of time on the wrong thing. 🙈

@hishamco
Copy link

Really I spent a lot of time based on your earlier description .. anyhow I will come back to continue o OrchardCore, hopefully I do some contributions on Umbraco Core

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

No branches or pull requests

8 participants