Dependency Injection

Aug 24, 2016 at 1:04 PM
Why SQLDependency depends on concretions and not of abstrations? Why not use dependency injection or contract resolver to create instances incase of use of Activator?
Aug 24, 2016 at 1:10 PM
SqlTableDependency inherit from TableDependency class, that in turn, implement public interface ITableDependency<T> where T : class
Aug 25, 2016 at 8:18 AM
I'm sorry, I haven't explained well myself. I saw that you create instaces by calling "Activator.CreateInstance" on "RecordChangedEventArgs<T>" , so to is needed that "T" will be a concretion.
 // See code: 

namespace TableDependency.EventArgs
{
    public class RecordChangedEventArgs<T> : System.EventArgs where T : class
    {
        protected readonly IEnumerable<PropertyInfo> EntiyProperiesInfo;
        protected IEnumerable<ColumnInfo> UserInterestedColumns;

        #region Properties

        internal MessagesBag MessagesBag { get; }
        public T Entity { get; protected set; }
        public ChangeType ChangeType { get; protected set; }
        public string MessageType { get; protected set; }

        #endregion

        #region Constructors

        internal RecordChangedEventArgs(MessagesBag messagesBag, ModelToTableMapper<T> mapper, IEnumerable<ColumnInfo> userInterestedColumns)
        {
            this.MessagesBag = messagesBag;
            this.EntiyProperiesInfo = ModelUtil.GetModelPropertiesInfo<T>();
            this.UserInterestedColumns = userInterestedColumns;

            ChangeType = messagesBag.MessageType;
            Entity = MaterializeEntity(messagesBag.MessageSheets, mapper);
        }

        #endregion

        #region Internal methods

        internal virtual T MaterializeEntity(List<Message> messages, ModelToTableMapper<T> mapper)
        {
            var entity = (T)Activator.CreateInstance(typeof(T));  // This is what i said. Maybe is important that we could say to a mapper how resolve instance.

            foreach (var entityPropertyInfo in this.EntiyProperiesInfo)
            {
                var propertyMappedTo = mapper?.GetMapping(entityPropertyInfo);
                var columnName = propertyMappedTo ?? entityPropertyInfo.Name;

                var message = messages.FirstOrDefault(m => string.Equals(m.Recipient, columnName, StringComparison.CurrentCultureIgnoreCase));
                if (message == default(Message)) continue;

                var dbColumnInfo = this.GetColumnInfo(columnName);

                var value = GetValue(entityPropertyInfo, dbColumnInfo, message.Body);
                entityPropertyInfo.SetValue(entity, value);
            }

            return entity;
        }

        internal virtual ColumnInfo GetColumnInfo(string columnName)
        {
            return this.UserInterestedColumns.First(uic => string.Equals(uic.Name, columnName, StringComparison.CurrentCultureIgnoreCase));
        }

        internal virtual object GetValue(PropertyInfo entityPropertyInfo, ColumnInfo columnInfo, byte[] message)
        {
            var formatCulture = new CultureInfo("en-US", false);
            var stringValue = this.MessagesBag.Encoding.GetString(message).ToString(formatCulture);
            var typeDescriptor = TypeDescriptor.GetConverter(entityPropertyInfo.PropertyType);
            var result = typeDescriptor.ConvertFromString(null, formatCulture, stringValue);
            return result;
        }

        #endregion
    }
}