ServiceType and abstract? classes

I’m registering some ServiceTypes and want to be able to have a default implementation of the service, with a possibility to override entire class or specific methods.

Tried an abstract class, but this cannot be registered.

Tried an ‘default’ implementation of the abstract class, but can only get that implementation, no other class that implements the same interface.

Tried an normal class with virtual methods, but can only get that implementation, no other class that implements the same interface.

Any ideas?

Litium version: 7.2.3

[Service(ServiceType = ...)]
public interface ....

public class ...Impl

Did you check this documentation?
https://docs.litium.com/documentation/architecture/dependency-injection

Yes! This doesn’t help. The service decorator is close to what we want but not completely.

The abstract class or the interface should be the service type

[Service(ServiceType = typeof(A))]
public abstract class A {}

Create an implementation that inherit the abstract class or interface. This class will automatic be found during application initialization.

public class AImpl : A {}

To let another implementation be used before the AImpl you need to add the service attribute on the default implementation and set the FallbackService = true, that will tell the registration process that the implementation should be used if no other implementations is found.

[Service(FallbackService = true)]
public class AImpl : A {}

public class ASuperImpl : A {}

If you build an extension and have a contract that need to be implemented in the project you can add the RequireServiceImplementationAttribute on the service registration and if no registered service is found the application will not start.

[Service(ServiceType = typeof(A))]
[RequireServiceImplementation]
public abstract class A {}
1 Like

What happens if you have
[Service(FallbackService = true)]
on 2 or more classes?

Do this work between namespaces/assemblies as well?

I’ve done what you suggest. But I end up with the default implementation anyway.

namespace x.y.z (same assembly)
[Service(ServiceType = typeof(EntityTypeService), Lifetime = DependencyLifetime.Transient)]
public abstract class EntityTypeService
{
    public abstract EntityType Get(ImportEntity importEntity);
}

namespace x.y.x (same assembly)
[Service(FallbackService = true)]
internal class EntityTypeServiceImpl : EntityTypeService
{
    public override EntityType Get(ImportEntity importEntity)
    {
        throw new System.NotImplementedException();
    }
}

namespace a.b.c (other assembly)
public class CustomEntityService : EntityTypeService
{
    public override EntityType Get(ImportEntity importEntity)
    {
        throw new System.NotImplementedException();
    }
}

Yes, it works between assemblies and namespaces, that is used in the product.

Then why do I get the default implementation still?.. Tried both interface and abstract class.

You haven’t the assembly registered as ignore for plugins? This setting can also be set with the assembly attribute AssemblyLoading.

Another possibility is that you missed one assembly redirects in the configuration file, this is needed when different components using the same component with different version numbers.

No.

It’s a standard Accelerator with an additional project in the solution.

Assembly redirect should not be required?

@patric.forsgard do you have any other ideas?

No, I haven’t. Is it possible for you to create a minimal project that you can PM me a link to so I can check how everything is setup for you?

Skype? Teams? VS Live Share?

Include the link to the downloadable code in a direct message here in the forum and I will download and check that code.

The solution was to have an interface or abstract class as base for the service. Then use the

[Service(ServiceType = typeof(Interface/Abstract), Fallback = true, Lifetime = DependencyLifetime.Transient)]

On the implementing type and not the interface or the abstract. E.g.:

namespace x.y.z {
    public interface IServiceImplementation { .. methods }
}

namespace x.y.z {
      [Service(ServiceType = typeof(IServiceImplementation ), Fallback = true, Lifetime = DependencyLifetime.Transient)]
      public class ServiceImplementation : IServiceImplementation { ... methods }
}

Maybe I missread your directons somehow? anyway maybe write this down in the documentation.