NopCommerce have resources available that will kick-start developers into custom plugin development. One article I recommend provides guidance on pouring the foundation of your plugin.
Further development of your plugin all depends on the business requirement. This includes any services, controllers, views you need to tweak or completely overhaul. This article dives into overriding, injecting and calling your custom service or nopCommerce service overrides.

Overriding nopcommerce services
Sometimes you will need to override the full functionality of a service. The example I have included was in an instance where the entire FormsAuthentication service had to be overridden to utilize a generic cookie for authentication instead of a System.Web.Security.FormsAuthenticationTicket.
1. Add a public class to your plugin project in the ‘Services’ folder. It should inherit the same interface of the service you want to replace and implement all of the methods required by the interface.
2. Add any additional services or repositories you will need in your plugin. Only the parameters required by the original service can be passed into the constructor---however, your service can be instantiated by manually resolving the service using Nop.Infrastructure.EngineContext.

   public class FormsAuthenticationService : Nop.Services.Authentication.IAuthenticationService
    {
        private readonly HttpContextBase _httpContext;
        private readonly ICustomerService _customerService;
        private readonly CustomerSettings _customerSettings;
        private readonly IEncryptionService _encryptionService;
 
        public FormsAuthenticationService(HttpContextBase httpContext, ICustomerService customerService, CustomerSettings customerSettings)
        {
            this._httpContext = httpContext;
            this._customerService = customerService;
            this._customerSettings = customerSettings;
            
            _encryptionService = EngineContext.Current.Resolve<IEncryptionService>();
        }
 
 
        public void SignIn(Customer customer, bool createPersistentCookie)...
               
        public void SignOut()...
                
        public Customer GetAuthenticatedCustomer()...
               
        private Customer GetAuthenticatedCustomerFromCookie()...
 
    }

3. Register your service in the DependancyRegister.cs. The register type must be your class name, the As extension should be set as the nopCommerce service you want to override.
builder.RegisterType<Nop.Plugin.Misc.AanCustom.Services.FormsAuthenticationService>().As<IAuthenticationService>().InstancePerHttpRequest();

Overriding selected methods in nopCommerce services
In most cases, only certain methods within a service need to be revised. Overriding an entire class could be excessive and unnecessary. Although this may require a little more effort than simply overriding the entire service, doing so would be a best practice to reduce redundant code, as well as to make unchanged methods available in case they need to be overriden by other plugins. To accomplish this without changing the core, do the following:
1. Add a public partial class to your plugin project in the ‘Services’ folder. It should inherit the base class that contains the method you want to override.
2. Add a constructor that implements the same parameters as the base class. Also add the private read-only variables that will be set on instantiation. The constructor/local variables can simply be copy/pasted from the nopCommerce service into your class.
3. Add any additional services or repositories you will need in your plugin. These services can be passed in as parameters in the constructor and will be implemented automatically using Autofac injection.
4. Add the overridden method(s) to your service using the override keyword. This method must accept the same parameters as the original method and return the same object type.
   public partial class PermissionService : Nop.Services.Security.PermissionService
   {
       
       private readonly IRepository<PermissionRecord> _permissionPecordRepository;
       private readonly ICustomerService _customerService;
       private readonly IWorkContext _workContext;
       private readonly ILocalizationService _localizationService;
       private readonly ILanguageService _languageService;
       
       private readonly IYourService _yourService;
 
       public PermissionService(
           IRepository<PermissionRecord> permissionPecordRepository,
           ICustomerService customerService,
           IYourService yourService,
           IWorkContext workContext,
           ILocalizationService localizationService,
           ILanguageService languageService,
           IYourService yourService)
           : base(permissionPecordRepository,
           customerService,
           workContext,
           localizationService,
           languageService,
           cacheManager)
       {
           this._permissionPecordRepository = permissionPecordRepository;
           this._customerService = customerService;
           this._workContext = workContext;
           this._localizationService = localizationService;
           this._languageService = languageService;
           this._yourService = yourService;
       }


       public override bool Authorize(string permissionRecordSystemName, Customer customer)
       {
          //Your logic here
       }
   }
5. Register your service in the DependancyRegister.cs. The register type must be your class name, the As extension should be set as the nopCommerce service you want to override.
builder.RegisterType<Nop.Plugin.Misc.AanCustom.Services.PermissionService>().As<IPermissionService>().InstancePerHttpRequest();

Handling unwanted dependency injection from uninstalled plugins
If a plugin is included in the solution but uninstalled, the expectation is that none of the code in the plugin is executed in the application. I have found that if a plugin is compiled and included in the solution, regardless of whether or not it is installed, the Register method in the DependancyRegister.cs file is always called — which registers the services into memory. This is because this class inherits from IDependancyRegister; and on application start, nopCommerce iterates through all classes that implements this interface and calls the Register method, regardless of whether the plugin is installed or uninstalled. Aside from the fact that unused services are registered into memory, any nopCommerce services you override with this plugin would still be registered and would still override the default nopCommerce service. Therefore, half of your plugin may be working when it shouldn’t be - which would cause unexpected problems.
To ensure your plugin is entirely “removed” from your application when uninstalled, insert the following code snippet at the top of the Register method in your plugins DependancyRegister.cs file, before any services/repositories are registered.
            var types = typeFinder.FindClassesOfType<IPluginFinder>(true);
 
            if (types.Count() == 1)
            {
                var plugins = Activator.CreateInstance(types.First()) as IPluginFinder;
                var descr = plugins.GetPluginDescriptorBySystemName("Misc.YourPluginName");
 
                if (descr == null || descr.Installed == false)
                {
                    return;
                }
            }

Tapping into dependency injected services/repositories “on-the-fly” Last but not least, and probably the most valuable snippet I have used during my nopCommerce plugin development experience, is the resolution of services and repositories from memory without having to identify the service in the constructor. In many cases, relying on service/repository injection within a constructor may cause recursive loops (if each service relies on one another). In other cases, dependency injection within a constructor is not possible if you require a service in, say, a Razor view. Also, use of the service may be limited to one seldom called function within a frequently called class---in this case, injecting the unused service repeatedly into the constructor may be cumbersome.
To retrieve a service or data repository “on-the-fly” simply obtain the nopCommerce infrastructure with the following code:
_encryptionService = EngineContext.Current.Resolve<IEncryptionService>();

Best Windows Hosting Recommendation

One of the most important things when choosing a good Windows hosting is the feature and reliability. HostForLIFE is the leading provider of Windows hosting, their servers are optimized for PHP web applications such as the latest ASP.NET version. The performance and the uptime of the hosting service are excellent and the features of the web hosting plan are even greater than what many hosting providers ask you to pay for.

At HostForLIFEASP.NET, customers can also experience fast Windows hosting. The company invested a lot of money to ensure the best and fastest performance of the datacenters, servers, network and other facilities. Its datacenters are equipped with the top equipments like cooling system, fire detection, high speed Internet connection, and so on. That is why HostForLIFEASP.NET guarantees 99.9% uptime for Windows. And the engineers do regular maintenance and monitoring works to assure its Windows hosting are security and always up.