Skip to content

Instantly share code, notes, and snippets.

@MelbourneDeveloper
Last active October 30, 2020 06:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MelbourneDeveloper/f8d68fd38d25fc8cd272b51467ba3bcf to your computer and use it in GitHub Desktop.
Save MelbourneDeveloper/f8d68fd38d25fc8cd272b51467ba3bcf to your computer and use it in GitHub Desktop.
This samples demonstrates how to decouple a class from any dependent types. This is a step up from injecting interfaces. This class approach means that the business service can be moved to an assembly that does not depend on any interfaces (types) for loading or saving..
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Linq;
namespace ConsoleApp2
{
class Program
{
static void Main()
{
var serviceCollection = new ServiceCollection()
.AddSingleton<BusinessService>();
typeof(PersonEntity).Assembly
.GetTypes()
.Where(t => t.GetInterfaces()
.Contains(typeof(IEntity)))
.ToList()
.ForEach(entityType =>
{
var funcType = typeof(Func<,>).MakeGenericType(entityType, entityType);
serviceCollection.AddSingleton(
funcType,
Delegate.CreateDelegate(
funcType,
DataLayer.Current,
typeof(DataLayer)
.GetMethod(nameof(DataLayer.Save))
.MakeGenericMethod(entityType)));
});
var person = serviceCollection.BuildServiceProvider().GetRequiredService<BusinessService>().SavePerson(new PersonEntity());
}
}
internal class DataLayer
{
public T Save<T>(T entity) => entity;
internal static DataLayer Current = new DataLayer();
}
public interface IEntity { }
public class PersonEntity : IEntity { }
public class AddressEntity : IEntity { }
public class ContactEntity : IEntity { }
public class BusinessService
{
readonly Func<PersonEntity, PersonEntity> _savePerson;
readonly Func<AddressEntity, AddressEntity> _saveAddress;
readonly Func<ContactEntity, ContactEntity> _saveContact;
public BusinessService(
Func<PersonEntity, PersonEntity> savePerson,
Func<AddressEntity, AddressEntity> saveAddress,
Func<ContactEntity, ContactEntity> saveContact
)
{
_savePerson = savePerson;
_saveAddress = saveAddress;
_saveContact = saveContact;
}
public PersonEntity SavePerson(PersonEntity person)
{
//Put business logic here
return _savePerson(person);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment