Last active
October 30, 2020 06:32
-
-
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..
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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